0 Prefacio
Pequeña tarea de inteligencia artificial, utilizando el aprendizaje profundo para identificar gatos en fotos, el requisito es usar solo una red neuronal de una sola capa.
1. Principio
1.1 Principio
El principio de este experimento consiste principalmente en ingresar una imagen, luego aplanarla, colocarla en una red neuronal completamente conectada de una sola capa para el entrenamiento y enviarla después del entrenamiento.
1.2 Modelo lineal
El modelo lineal es el tipo de modelo más común. En la mayoría de las tareas, los modelos lineales son los más efectivos.
Usando la expresión de error más común del modelo lineal, necesitamos ajustar constantemente w para hacer que la pérdida sea menor al juzgar si el error es menor que nuestro umbral.
1.3 Descenso de gradiente
1.4 Función de activación
La función de activación utilizada en este experimento es la función sigmoidea. La función principal de la función de activación es proporcionar la capacidad de modelado no lineal de la red. Si no hay una función de activación, la red solo puede expresar un mapa lineal. En este momento, incluso si hay más capas ocultas, toda la red es equivalente a una red neuronal de una sola capa. Por lo tanto, se puede considerar que solo después de agregar la función de activación, la red neuronal profunda tiene la capacidad de aprender el mapeo no lineal jerárquico. A continuación se muestra la fórmula para la función de activación.
1.2 Entorno operativo
El código usa pytorch para experimentos, y la versión de python es 3.7
pitón | 3.7 |
---|---|
Cuda |
1.3 Conjunto de datos
2. Código
import json
import os
import sys
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms, datasets
from tqdm import tqdm
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# print("using {} device.".format(device))
data_transform = {
"train": transforms.Compose([transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),
"val": transforms.Compose([transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])}
data_root = os.path.abspath(os.path.join(os.getcwd(), "./")) # get data root path
image_path = os.path.join(data_root, "data", "cats_and_dogs_v2") # flower data set path
#assert 在表达式条件为 False 的时候触发异常。 断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况。
assert os.path.exists(image_path), "{} path does not exist.".format(image_path)
train_dataset = datasets.ImageFolder(root=os.path.join(image_path, "train"),
transform=data_transform["train"])
train_num = len((train_dataset))
print(train_num)
train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=1, shuffle=True,num_workers=0)
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
self.lin1 = torch.nn.Linear(150528, 800)
self.lin2 = torch.nn.Linear(800, 400)
self.lin3 = torch.nn.Linear(400, 2)
self.sigmoid = torch.nn.Sigmoid()
def forward(self, x):
x = self.sigmoid(self.lin1(x))
x = self.sigmoid(self.lin2(x))
x = self.sigmoid(self.lin3(x))
return x
model = Model()
model = model.cuda()
criterion = torch.nn.CrossEntropyLoss() #这是损失函数吗?
criterion = criterion.cuda()
#SGD是随机梯度下降(stochastic gradient descent)的首字母
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
for epoch in range(100):
correct = 0
for i, data in enumerate(train_loader, 0): # train_loader 是先shuffle后mini_batch
inputs, labels = data #input是输入tensor,label是标签
inputs = inputs.cuda()
labels = labels.cuda()
inputs = torch.reshape(inputs,[1,150528])
y_pred = model(inputs)
if(torch.argmax(y_pred) == labels):
correct += 1
loss = criterion(y_pred, labels)
optimizer.zero_grad() # 清除网络状态
loss.backward() # loss反向传播
optimizer.step() # 更新参数
print('第', epoch, '轮的准确度是:%d %%' % (100 * correct / train_num))