Directorio de artículos
1. Lectura de datos
PyTorch nos proporciona un mecanismo de lectura de datos muy conveniente, es decir, usar la combinación de la clase Dataset y la clase DataLoader para obtener el iterador de datos. Durante el entrenamiento o la predicción, el iterador de datos puede generar los datos necesarios para cada lote y realizar las operaciones correspondientes de preprocesamiento y mejora de datos en los datos.
Veamos la clase Dataset y la clase DataLoader por separado.
1. Clase de conjunto de datos
La clase Dataset en PyTorch es una clase abstracta que se puede usar para representar conjuntos de datos. Heredamos la clase Dataset para personalizar el formato, el tamaño y otros atributos del conjunto de datos, que la clase DataLoader puede usar directamente más adelante.
De hecho, esto significa que ya sea que use un conjunto de datos personalizado o un conjunto de datos oficial empaquetado para nosotros, su esencia es heredar la clase Dataset. Al heredar la clase Dataset, al menos los siguientes métodos deben reescribirse:
- __ init __() : Constructor, que puede personalizar el método de lectura de datos y el preprocesamiento de datos;
- __len __() : devuelve el tamaño del conjunto de datos ;
- __getitem __() : indexa ciertos datos en el conjunto de datos.
No es fácil de entender con solo mirar el principio. Escribamos un ejemplo simple para ver cómo usar la clase Dataset para definir un conjunto de datos de tipo Tensor.
import torch
from torch.utils.data import Dataset
class MyDataset(Dataset):
# 构造函数
def __init__(self, data_tensor, target_tensor):
self.data_tensor = data_tensor
self.target_tensor = target_tensor
# 返回数据集大小
def __len__(self):
return self.data_tensor.size(0)
# 返回索引的数据与标签
def __getitem__(self, index):
return self.data_tensor[index], self.target_tensor[index]
Combinado con el código, podemos ver que hemos definido un conjunto de datos llamado MyDataset. En el constructor, los datos y las etiquetas del tipo Tensor se pasan; en la función __len__, el tamaño del Tensor se devuelve directamente ; en __getitem__ Los datos y las etiquetas del índice se devuelven en la función.
A continuación, echemos un vistazo a cómo llamar al conjunto de datos que acabamos de definir. Primero genere aleatoriamente un tensor de datos de 10*3 dimensiones y luego genere un tensor de etiqueta de 10 dimensiones correspondiente al tensor de datos. Utilice estos dos tensores para generar un objeto MyDataset. Puede usar directamente la función len() para verificar el tamaño del conjunto de datos, y puede usar directamente el subíndice para llamar a los datos del índice.
# 生成数据
data_tensor = torch.randn(10, 3)
target_tensor = torch.randint(2, (10,)) # 标签是0或1
# 将数据封装成Dataset
my_dataset = MyDataset(data_tensor, target_tensor)
# 查看数据集大小
print('Dataset size:', len(my_dataset))
'''
输出:
Dataset size: 10
'''
# 使用索引调用数据
print('tensor_data[0]: ', my_dataset[0])
'''
输出:
tensor_data[0]: (tensor([ 0.4931, -0.0697, 0.4171]), tensor(0))
'''
2. Clase de cargador de datos
En un proyecto real, si la cantidad de datos es grande, teniendo en cuenta problemas como la memoria limitada y la velocidad de E/S, es imposible cargar todos los datos en la memoria al mismo tiempo durante el proceso de entrenamiento, ni se puede cargar por solo un proceso Por lo tanto, se requieren cargas multiproceso e iterativas, y DataLoader está diseñado en función de estas necesidades.
DataLoader es un iterador. La forma más básica de usarlo es pasar un objeto Dataset. Generará un lote de datos de acuerdo con el valor del parámetro batch_size. Mientras ahorra memoria, también puede implementar procesos múltiples y codificación de datos. .
La clase DataLoader se llama de la siguiente manera:
from torch.utils.data import DataLoader
tensor_dataloader = DataLoader(dataset=my_dataset, # 传入的数据集, 必须参数
batch_size=2, # 输出的batch大小
shuffle=True, # 数据是否打乱
num_workers=0) # 进程数, 0表示只有主进程
# 以循环形式输出
for data, target in tensor_dataloader:
print(data, target)
'''
输出:
tensor([[-0.1781, -1.1019, -0.1507],
[-0.6170, 0.2366, 0.1006]]) tensor([0, 0])
tensor([[ 0.9451, -0.4923, -1.8178],
[-0.4046, -0.5436, -1.7911]]) tensor([0, 0])
tensor([[-0.4561, -1.2480, -0.3051],
[-0.9738, 0.9465, 0.4812]]) tensor([1, 0])
tensor([[ 0.0260, 1.5276, 0.1687],
[ 1.3692, -0.0170, -1.6831]]) tensor([1, 0])
tensor([[ 0.0515, -0.8892, -0.1699],
[ 0.4931, -0.0697, 0.4171]]) tensor([1, 0])
'''
# 输出一个batch
print('One batch tensor data: ', iter(tensor_dataloader).next())
'''
输出:
One batch tensor data: [tensor([[ 0.9451, -0.4923, -1.8178],
[-0.4046, -0.5436, -1.7911]]), tensor([0, 0])]
'''
Combinado con el código, clasifiquemos varios parámetros en DataLoader, que representan respectivamente:
- conjunto de datos: tipo de conjunto de datos, conjunto de datos de entrada, parámetros requeridos;
- batch_size: tipo int, cuántas muestras hay en cada lote;
- barajar: tipo booleano, al comienzo de cada época, si se reorganizan los datos;
- num_workers: tipo int, el número de procesos para cargar datos, 0 significa que todos los datos se cargarán en el proceso principal, el valor predeterminado es 0.
2. El proceso de construcción de una red neuronal en Pytorch
Enlace original: Domina el proceso de construcción de una red neuronal en Pytorch en diez minutos .
Si desea crear una red, primero debe definir una Clase y heredar nn.Module (esto es necesario, así que primero importe torch.nn como nn, nn es una caja de herramientas, muy útil), llamamos el nombre de la clase en red.
Class Net(nn.Module):
Hay principalmente dos funciones escritas en esta clase, una es la función __init__ inicializada y la otra es la función de avance. Tomemos uno al azar, de la siguiente manera:
def __init__(self):
super().__init__()
self.conv1=nn.Conv2d(1,6,5)
self.conv2=nn.Conv2d(6,16,5)
def forward(self, x):
x=F.max_pool2d(F.relu(self.conv1(x)),2)
x=F.max_pool2d(F.relu(self.conv2(x)),2)
return x
- __ init __ es para definir la capa convolucional Por supuesto, primero debe hacer super() para inicializar la clase principal nn.Module. (Conocimiento básico de Python) Lo principal aquí es definir la capa convolucional, por ejemplo, la primera capa, la llamamos conv1, y la definimos como una convolución con 1 canal de entrada, 6 canales de salida y kernel de convolución 5*5 capa Conv2 es lo mismo. El "aprendizaje profundo" de la red neuronal es en realidad principalmente para aprender los parámetros en el kernel de convolución, como otras cosas que no necesitan ser aprendidas y cambiadas, así que no las introduzca. Por ejemplo, la función de activación relu(), si hay que ponerla, también es posible llamarla myrelu.
- Adelante es donde realmente se ejecuta el flujo de datos. Por ejemplo, en el código anterior, la entrada x se pasa primero a través de conv1 definido (este nombre es su propio nombre), y luego a través de la función de activación F.relu() (este no es un nombre que usted mismo nombró, debe primero importe torch.nn .funcional como F, F.relu() es una función oficial. Por supuesto, si define relu en __init__ como el myrelu que mencioné anteriormente, entonces la primera oración aquí se convierte en x=F. max_pool2d(myrelu( self.conv1(x)), 2). La agrupación F.max_pool2d en el siguiente paso es la misma, no más tonterías. Después de una serie de flujos, finalmente devuelva x al exterior.
- La definición de Clase de esta Red presta atención principalmente a dos puntos . El primero : preste atención a la consistencia del canal de salida y el canal de entrada antes y después. La primera capa convolucional no puede generar 4 canales y la segunda puede ingresar 6 canales, por lo que se informará un error. Segundo : es un poco diferente de nuestra clase normal de python, ¿la has encontrado? ¿Cómo debemos usar esta Red? Primero defina una instancia de Net (después de todo, Net es solo una clase y no puede pasar parámetros directamente, salida = Net (entrada) por supuesto que no)
net=Net()
De esta manera, podemos pasar x, asumiendo que ya tiene una "entrada" de datos de entrada a la red neuronal (esta entrada debe definirse como tipo de tensor, cómo definir tensor, luego lea el libro usted mismo. Además, hay tres puntos de pytorch Para varias versiones, debe convertirlo en un tipo Variable, que no es necesario después de 4.0) Al pasar, es:
output=net(input)
Mira la definición anterior:
def __init__(self):
……
def forward(self, x):
……
Es un poco raro. Parece que Python normal generalmente pasa datos x a la clase. En la definición de la clase, esta x debe pasarse a la función __init__ como un parámetro formal. En la definición anterior, x se pasa como un parámetro formal dentro la función de avance. De hecho, no es contradictorio, porque cuando define net, es net=Net(), y no se le pasan parámetros. Si desea pasar según sea necesario durante la inicialización, simplemente pase lo que necesita. Es solo que x es la entrada de la red neuronal, pero no se requiere para la inicialización Para inicializar una red, ¿debe haber datos de entrada? No necesariamente. Es solo que cuando se pasa a la red, automáticamente pensará que su x se alimenta al reenvío.
Una vez que se define la red, implica pasar parámetros, calcular errores, propagar hacia atrás, actualizar pesos... Es muy fácil olvidar el formato y el orden de estas cosas. La forma de pasar se ha introducido anteriormente, que es equivalente a una propagación directa, y se calcula la entrada x de cada capa a lo largo del camino. Si desea que la salida de la red neuronal sea similar a la realidad básica que espera, es decir, reducir continuamente la diferencia entre los dos. Esta diferencia la define usted mismo, es decir, la función de objeto o la función de pérdida. . Si la pérdida de la función de pérdida se aproxima a 0, entonces el objetivo se logra naturalmente. La pérdida de función de pérdida básicamente no puede llegar a 0, pero se espera que pueda alcanzar el valor mínimo, por lo que se espera que pueda descender de acuerdo con el gradiente. Todo el mundo debería estar familiarizado con la fórmula del descenso de gradiente. Si no está familiarizado con ella, se recomienda leer la teoría correspondiente. Es solo que usted determina su entrada, entonces, ¿qué puede aprender y decidir la red neuronal? Naturalmente, solo puede determinar el peso de cada capa convolucional. Entonces, la red neuronal solo puede modificar el peso continuamente, como y = wx + b, x lo proporciona usted, solo puede cambiar w, b para hacer que la salida final y sea lo más cercana posible al valor y que desea, entonces que la pérdida aumentará más pequeño. Si la derivada parcial de pérdida del parámetro W en la capa convolucional es cercana a 0, ¿no significa que ha alcanzado un valor mínimo? Y cuando se haya dado su método de cálculo de pérdida, la reducción de la derivada parcial de pérdida con respecto a w solo se puede realizar actualizando el parámetro W de la capa de convolución de parámetros (otras cosas no se pueden determinar, se trata de su entrada y cuál proporcionó). Por lo tanto, la actualización de W se realiza de la siguiente manera: ( Tenga en cuenta estos números, que se mencionarán a continuación ) [1] Primero calcule la derivada parcial de la pérdida para la entrada x, (por supuesto, hay varias capas en la red , y esta x se refiere a cada entrada de capa, no a la entrada original); [2] multiplica el resultado de [1] por un tamaño de paso (esto es equivalente a modificar el parámetro W); [3] usa W para restar esta modificación Cantidad, para completar una modificación del parámetro W.No es muy preciso, pero el significado general es este. Puede implementar este proceso manualmente, pero ¿cómo se puede implementar manualmente una red neuronal a gran escala? Eso es imposible. Así que vamos a usar el framework pytorch y la caja de herramientas torch.nn. Entonces, para definir la función de pérdida, tome MSEloss como ejemplo
compute_loss=nn.MSELoss()
Obviamente, también es una clase y no puede pasar directamente los datos de entrada, por lo que direct loss=nn.MSEloss(target, output) es incorrecto. A esta función se le debe asignar una instancia llamada compute_loss. Luego puede pasar la salida de su red neuronal y el objetivo de respuesta estándar:
loss=compute_loss(target,output)
Calcule la pérdida, el siguiente paso es retropropagación :
loss.backward()
Este paso es en realidad para calcular [1] y obtener la cantidad de actualización del parámetro W en un solo paso , que se considera una propagación hacia atrás . Preste atención aquí, ¿qué es loss.backward()? Si es su propia pérdida definida (por ejemplo, define una pérdida definida (x, y): devuelva yx), entonces definitivamente se equivocará directamente hacia atrás. Por lo tanto, debe usar las funciones proporcionadas en nn. Por supuesto, es imposible usar solo la función de pérdida oficial para el aprendizaje profundo, por lo que si desea usar su propia función de pérdida, también debe definir la pérdida como la red anterior (de lo contrario, su pérdida no se puede propagar hacia atrás, este punto debe ser notado , Nota: Este punto fue escrito antes, la versión hace mucho tiempo no funcionó, pero ahora está bien, básicamente ya no es necesario), también hereda nn.Module, coloca los parámetros entrantes en el reenvío, y el la pérdida específica está en el delantero Olvídalo, y finalmente vuelve la pérdida. __init()__ está vacío, solo escribe super().__init__. Después de la retropropagación, ¿cómo lograr [2] y [3]? Se logra a través del optimizador. Deje que el optimizador actualice automáticamente el peso de la red W. Entonces, después de definir Net , debe escribir una definición de optimizador (elija el método SGD como ejemplo):
from torch import optim
optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)
De manera similar, el optimizador también es una clase, primero defina un optimizador de instancia y luego utilícelo más tarde. Tenga en cuenta que cuando se define el optimizador, es necesario pasar los parámetros de la red a SGD, para que el optimizador tenga control sobre los parámetros de la red y pueda modificarlos. Al pasar, la tasa de aprendizaje lr también se pasa . Antes de cada iteración, primero borre el gradiente almacenado en el optimizador (porque la "cantidad de actualización" que ha actualizado W no se usará la próxima vez)
optimizer.zero_grad()
Después de la retropropagación loss.backward(), actualice los parámetros:
optimizer.step()
Entonces nuestra sucesión es:
- Primero defina la red: escriba la Clase de la red Net, declare la instancia net=Net() de la red,
- definir el optimizador optimizador=optim.xxx(net.parameters(), lr=xxx),
- Luego defina la función de pérdida (escriba su propia clase o use la oficial directamente, compute_loss=nn.MSELoss() u otras.
- Una vez completada la definición, comience el ciclo una y otra vez: ① Primero borre la información de gradiente en el optimizador, Optimizer.zero_grad(); ② Luego pase la entrada, salida=neta(entrada), propagación directa ③ Calcule la pérdida, loss= compute_loss(objetivo, salida) ##Aquí el objetivo es el valor estándar de referencia GT, que debe preparar usted mismo, y corresponde a la entrada pasada antes ④ Propagación hacia atrás del error, loss.backward() ⑤Actualizar parámetros, Optimizer.step () así Se implementa una red neuronal básica. El entrenamiento de la mayoría de las redes neuronales se puede simplificar a este proceso, nada más que la complejidad del contenido entrante, la complejidad de la definición de la red, la complejidad de la función de pérdida, etc. Gracias por señalar dónde hay un problema.
3. Capa de convolución
La capa convolucional escanea y opera el mapa de características multicanal (canal) de entrada a través de un número específico de núcleos de convolución (también conocidos como filtros), para obtener múltiples mapas de características de salida con información semántica de nivel superior (el número de canales es igual al número de volumen de núcleos).
3.1 Capa de convolución unidimensional: torch.nn.Conv1d()
class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
Capa convolucional unidimensional, la escala de entrada es (N,C_in,L_in) , la escala de salida es (N,C_out,L_out)
3.1.1 Descripción de los parámetros:
- in_channels (int) – canales de la señal de entrada
- out_channels (int) – los canales producidos por la convolución
- kerner_size (int o tuple) - el tamaño del kernel de convolución
- zancada (int o tupla, opcional) - zancada de convolución
- padding (int o tuple, opcional) - el número de capas de 0 agregadas a cada borde de la entrada
- dilatación (int o tupla, `opcional``) – espacio entre los elementos del kernel de convolución
- grupos (int, opcional) – Número de conexiones de bloqueo de los canales de entrada a los canales de salida. grupo=1, la salida es la convolución de todas las entradas; grupo=2, esto es equivalente a tener dos capas convolucionales una al lado de la otra, cada capa convolucional calcula la mitad del canal de entrada, y la salida generada es la mitad del canal de salida, y luego conecte las dos salidas juntas.
- sesgo (bool, opcional) : si sesgo = Verdadero, agregue un sesgo
3.1.2. ejemplo:
m = nn.Conv1d(16, 33, 3, stride=2)
input = autograd.Variable(torch.randn(20, 16, 50))
output = m(input)
3.2 Capa de convolución bidimensional: torch.nn.Conv2d()
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
Capa convolucional bidimensional, la escala de entrada es (N,C_in,H_in,W_in) y la escala de salida es (N,C_out,H_out,W_out)
- 2.1 Descripción del parámetro:
- in_channels (int) – canales de la señal de entrada
- out_channels (int) – los canales producidos por la convolución
- kerner_size (int o tuple) - el tamaño del kernel de convolución
- zancada (int o tupla, opcional) – zancada de convolución
- padding (int o tuple, opcional) - el número de capas de 0 agregadas a cada borde de la entrada
- dilatación (int o tuple, opcional) – espacio entre los elementos del kernel de convolución
- grupos (int, opcional) – número de conexiones de bloqueo del canal de entrada al canal de salida
- sesgo (bool, opcional) : si sesgo = Verdadero, agregue un sesgo
3.2.2. ejemplo:
# With square kernels and equal stride
m = nn.Conv2d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
# non-square kernels and unequal stride and with padding and dilation
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)
3.3 Capa de convolución tridimensional: torch.nn.Conv3d()
class torch.nn.Conv3d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
Capa convolucional tridimensional, la escala de entrada es (N, C_in,D,H,W) y la escala de salida es (N, C_out, D_out, H_out,W_out)
3.3.1 Descripción de los parámetros:
- in_channels (int) – canales de la señal de entrada
- out_channels (int) – los canales producidos por la convolución
- kerner_size (int o tuple) - el tamaño del kernel de convolución
- zancada (int o tupla, opcional) – zancada de convolución
- padding (int o tuple, opcional) - el número de capas de 0 agregadas a cada borde de la entrada
- dilatación (int o tuple, opcional) – espacio entre los elementos del kernel de convolución
- grupos (int, opcional) – número de conexiones de bloqueo del canal de entrada al canal de salida
- sesgo (bool, opcional) : si sesgo = Verdadero, agregue un sesgo
3.2. ejemplo:
# With square kernels and equal stride
m = nn.Conv3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(4, 2, 0))
input = autograd.Variable(torch.randn(20, 16, 10, 50, 100))
output = m(input)
4. Capa de agrupación
En la red neuronal convolucional, generalmente se agrega una capa de agrupación entre capas convolucionales adyacentes.La capa de agrupación puede reducir efectivamente el tamaño de la matriz de parámetros, reduciendo así la cantidad de parámetros en la última capa de conexión. Por lo tanto, agregar una capa de agrupación puede acelerar el cálculo y evitar el sobreajuste.
4.1 Agrupación máxima unidimensional: torch.nn.MaxPool1d()
class torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
如果输入的大小是 (N,C_in,L_in),那么输出的大小是 (N,C_out,L_out)
4.1.1. 参数说明:
- kernel_size(int or tuple) - max pooling的窗口大小
- stride(int or tuple,optional) - max pooling的窗口移动的步长。默认值是kernel_size
- padding(int or tuple,optional) - 输入的每一条边补充0的层数
- dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
- return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
- ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
4.1.2. example:
# pool of size=3, stride=2
m = nn.MaxPool1d(3, stride=2)
input = autograd.Variable(torch.randn(20, 16, 50))
output = m(input)
4.2. 2维最大池化:torch.nn.MaxPool2d()
class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
如果输入的大小是 (N,C, H i n H_{in} Hin, W i n W_{in} Win),那么输出的大小是 (N,C, H o u t H_{out} Hout, W o u t W_{out} Wout)
4.2.1. 参数说明:
- kernel_size(int or tuple) - max pooling的窗口大小
- stride(int or tuple,optional) - max pooling的窗口移动的步长。默认值是kernel_size
- padding(int or tuple,optional) - 输入的每一条边补充0的层数
- dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
- return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
- ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
4.2.2. example:
# pool of square window of size=3, stride=2
m = nn.MaxPool2d(3, stride=2)
# pool of non-square window
m = nn.MaxPool2d((3, 2), stride=(2, 1))
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
4.3. 3维最大池化:torch.nn.MaxPool3d()
class torch.nn.MaxPool3d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
如果输入的大小是 (N,C,D,H,W),那么输出的大小是 (N,C,D , H o u t ,H_{out} ,Hout, W o u t W_{out} Wout)
4.3.1. 参数说明:
- kernel_size(int or tuple) - max pooling的窗口大小
- stride(int or tuple,optional) - max pooling的窗口移动的步长。默认值是kernel_size
- padding(int or tuple,optional) - 输入的每一条边补充0的层数
- dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
- return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
- ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
4.3.2. example:
# pool of square window of size=3, stride=2
m = nn.MaxPool3d(3, stride=2)
# pool of non-square window
m = nn.MaxPool3d((3, 2, 2), stride=(2, 1, 2))
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
五、非线性激活层
5.1. torch.nn.ReLU()
class torch.nn.ReLU(inplace=False)
5.1.1 参数:
- inplace-选择是否进行覆盖运算
5.1.2 example:
m = nn.ReLU()
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
5.2. torch.nn.ELU()
class torch.nn.ELU(alpha=1.0, inplace=False)
5.2.1 参数:
- inplace-选择是否进行覆盖运算
5.2.2 example:
m = nn.ELU()
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
5.3. torch.nn.LeakyReLU()
class torch.nn.LeakyReLU(negative_slope=0.01, inplace=False)
5.3.1 参数:
- inplace-选择是否进行覆盖运算
- negative_slope:控制负斜率的角度,默认等于0.01
5.3.2 example:
m = nn.LeakyReLU(0.1)
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
5.4. torch.nn.Softmax()
对n维输入张量运用Softmax函数,将张量的每个元素缩放到(0,1)区间且和为1。
class torch.nn.Softmax()
5.4.1 example:
m = nn.Softmax()
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
5.5. torch.nn.Sigmoid()
对n维输入张量运用Softmax函数,将张量的每个元素缩放到(0,1)区间且和为1。
class torch.nn.Sigmoid()
5.5.1 example:
m = nn.Sigmoid()
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
5.6. torch.nn.Tanh ()
对n维输入张量运用Softmax函数,将张量的每个元素缩放到(0,1)区间且和为1。
class torch.nn.Tanh()
5.6.1 example:
m = nn.Tanh()
input = autograd.Variable(torch.randn(2))
print(input)
print(m(input))
六、归一化层
6.1. torch.nn.BatchNorm1d()
对小批量(mini-batch)的2d或3d输入进行批标准化(Batch Normalization)操作
class torch.nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True)
y = x − m e a n [ x ] V a r [ x ] + ϵ ∗ g a m m a + b e t a y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta y=Var[x]+ϵx−mean[x]∗gamma+beta
在每一个小批量(mini-batch)数据中,计算输入各个维度的均值和标准差。gamma与beta是可学习的大小为C的参数向量(C为输入大小)。
在训练时,该层计算每次输入的均值与方差,并进行移动平均。移动平均默认的动量值为0.1。
在验证时,训练求得的均值/方差将用于标准化验证数据。
6.1.1 参数:
- num_features: 来自期望输入的特征数,该期望输入的大小为’batch_size x num_features [x
width]’ - eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
- momentum:动态均值和动态方差所使用的动量。默认为0.1。
- affine:一个布尔值,当设为true,给该层添加可学习的仿射变换参数。
Shape: - 输入:(N, C)或者(N, C, L) - 输出:(N, C)或者(N,C,L)(输入输出相同)
6.1.2 example:
# With Learnable Parameters
m = nn.BatchNorm1d(100)
# Without Learnable Parameters
m = nn.BatchNorm1d(100, affine=False)
input = autograd.Variable(torch.randn(20, 100))
output = m(input)
6.2. torch.nn.BatchNorm2d()
对小批量(mini-batch)3d数据组成的4d输入进行批标准化(Batch Normalization)操作
class torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True)
y = x − m e a n [ x ] V a r [ x ] + ϵ ∗ g a m m a + b e t a y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta y=Var[x]+ϵx−mean[x]∗gamma+beta
在每一个小批量(mini-batch)数据中,计算输入各个维度的均值和标准差。gamma与beta是可学习的大小为C的参数向量(C为输入大小)。
在训练时,该层计算每次输入的均值与方差,并进行移动平均。移动平均默认的动量值为0.1。
在验证时,训练求得的均值/方差将用于标准化验证数据。
6.2.1 参数:
- num_features: 来自期望输入的特征数,该期望输入的大小为’batch_size x num_features x height x width’
- eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
- momentum:动态均值和动态方差所使用的动量。默认为0.1。
- affine:一个布尔值,当设为true,给该层添加可学习的仿射变换参数。
Shape: - 输入:(N, C,H, W) - 输出:(N, C, H, W)(输入输出相同)
6.2.2 example:
# With Learnable Parameters
m = nn.BatchNorm2d(100)
# Without Learnable Parameters
m = nn.BatchNorm2d(100, affine=False)
input = autograd.Variable(torch.randn(20, 100, 35, 45))
output = m(input)
6.3. torch.nn.BatchNorm3d()
对小批量(mini-batch)4d数据组成的5d输入进行批标准化(Batch Normalization)操作
class torch.nn.BatchNorm3d(num_features, eps=1e-05, momentum=0.1, affine=True)
y = x − m e a n [ x ] V a r [ x ] + ϵ ∗ g a m m a + b e t a y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta y=Var[x]+ϵx−mean[x]∗gamma+beta
在每一个小批量(mini-batch)数据中,计算输入各个维度的均值和标准差。gamma与beta是可学习的大小为C的参数向量(C为输入大小)。
在训练时,该层计算每次输入的均值与方差,并进行移动平均。移动平均默认的动量值为0.1。
在验证时,训练求得的均值/方差将用于标准化验证数据。
6.3.1 参数:
- num_features: 来自期望输入的特征数,该期望输入的大小为 ‘batch_size x num_features depth x height x width’
- eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
- momentum:动态均值和动态方差所使用的动量。默认为0.1。
- affine:一个布尔值,当设为true,给该层添加可学习的仿射变换参数。
Shape: - 输入:(N, C,D, H, W) - 输出:(N, C, D, H, W)(输入输出相同)
6.3.2 example:
# With Learnable Parameters
m = nn.BatchNorm3d(100)
# Without Learnable Parameters
m = nn.BatchNorm3d(100, affine=False)
input = autograd.Variable(torch.randn(20, 100, 35, 45, 10))
output = m(input)
七、线性层
class torch.nn.Linear(in_features, out_features, bias=True)
对输入数据做线性变换:(y = Ax + b)
7.1.参数:
- in_features - 每个输入样本的大小
- out_features - 每个输出样本的大小
- bias - 若设置为False,这层不会学习偏置。默认值:True
7.2.shape
- 输入: (N,in_features)
- 输出: (N,out_features)
7.3.example
m = nn.Linear(20, 30)
input = autograd.Variable(torch.randn(128, 20))
output = m(input)
print(output.size())
八、Dropout layers
class torch.nn.Dropout(p=0.5, inplace=False)
随机将输入张量中部分元素设置为0。对于每次前向调用,被置0的元素都是随机的。
8.1.参数:
- p - 将元素置0的概率。默认值:0.5
- in-place - 若设置为True,会在原地执行操作。默认值:False
8.2.shape
- 输入: 任意。输入可以为任意形状。
- 输出: 相同。输出和输入形状相同。
8.3.example
m = nn.Dropout(p=0.2)
input = autograd.Variable(torch.randn(20, 16))
output = m(input)
九、Loss functions
基本用法:
criterion = LossCriterion() #构造函数有自己的参数
loss = criterion(x, y) #调用标准时也有参数
9.1. torch.nn.L1Loss()
原型:
class torch.nn.L1Loss(size_average=True)
创建一个衡量输入x(模型预测输出)和目标y之间差的绝对值的平均值的标准。计算公式:
l o s s ( x , y ) = 1 / n ∑ ∣ x i − y i ∣ loss(x,y)=1/n\sum|x_i-y_i| loss(x,y)=1/n∑∣xi−yi∣
参数:
- x 和 y 可以是任意形状,每个包含n个元素。
- 对n个元素对应的差值的绝对值求和,得出来的结果除以n。
- 如果在创建L1Loss实例的时候在构造函数中传入size_average=False,那么求出来的绝对值的和将不会除以n
9.2. torch.nn.MSELoss()
原型:
class torch.nn.MSELoss(size_average=True)
创建一个衡量输入x(模型预测输出)和目标y之间差均方误差标准。计算公式:
l o s s ( x , y ) = 1 / n ∑ ( x i − y i ) 2 loss(x,y)=1/n\sum(x_i-y_i)^2 loss(x,y)=1/n∑(xi−yi)2
参数:
- x 和 y 可以是任意形状,每个包含n个元素。
- 对n个元素对应的差值的绝对值求和,得出来的结果除以n。
- 如果在创建MSELoss实例的时候在构造函数中传入size_average=False,那么求出来的平方和将不会除以n
9.3. torch.nn.CrossEntropyLoss()
原型:
class torch.nn.CrossEntropyLoss(weight=None, size_average=True)
此标准将 LogSoftMax 和 NLLLoss 集成到一个类中。
当训练一个多类分类器的时候,这个方法是十分有用的。
- weight(tensor): 1-D tensor,n个元素,分别代表n类的权重,如果你的训练样本很不均衡的话,是非常有用的。默认值为None。
l o s s ( x , y ) = 1 / n ∑ ( x i − y i ) 2 loss(x,y)=1/n\sum(x_i-y_i)^2 loss(x,y)=1/n∑(xi−yi)2
调用时参数:
- input : 包含每个类的得分, 2-D tensor, shape 为 batch*n
- target: 大小为 n 的 1—D tensor,包含类别的索引 (0到 n-1) 。
Loss可以表述为以下形式:
当weight参数被指定的时候,loss的计算公式变为:
l o s s ( x , c l a s s ) = w e i g h t s [ c l a s s ] ∗ ( − x [ c l a s s ] + l o g ( ∑ j e x p ( x [ j ] ) ) ) loss(x, class) = weights[class] * (-x[class] + log(\sum_j exp(x[j]))) loss(x,class)=weights[class]∗(−x[class]+log(j∑exp(x[j])))
计算出的loss对mini-batch的大小取了平均。
shape:
- Input: (N,C) C 是类别的数量
- Target: (N) N是mini-batch的大小,0 <= targets[i] <= C-1