人工智能小作业,使用深度学习识别照片中的猫,要求是只使用单层神经网络。
本实验原理主要通过输入图像,然后通过将图像展平,放入单层全连接神经网络训练,训练后进行输出。
线性模型是最常见的一种模型。在大部分的任务中,线性模型是最有效的。
使用线性模型最常见的误差表达方式,我们需要通过判断误差是否小于我们的阈值,不断的调整w使它使loss损失更小。
本实验使用的激活函数为sigmoid函数。激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此可以认为,只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。以下是激活函数的公式。
代码使用pytorch进行试验,python版本为3.7
python | 3.7 |
---|---|
cuda |
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))