import torch
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST
import matplotlib.pyplot as plt
class Net(torch.nn.Module):
def __init__(self):#初始化
super().__init__()#torch.nn.Module初始化
self.fc1 = torch.nn.Linear(28 * 28, 64)#初始化一个点阵
self.fc2 = torch.nn.Linear(64, 64)
self.fc3 = torch.nn.Linear(64, 64)
self.fc4 = torch.nn.Linear(64, 64)
self.fc5 = torch.nn.Linear(64, 10)
def forward(self, x):#神经网络训练函数,这个是四层的,self.fc1(x)为线性计算,如何在外面套一个激活函数来解决非线性的问题
x = torch.nn.functional.relu(self.fc1(x))
x = torch.nn.functional.relu(self.fc2(x))
x = torch.nn.functional.relu(self.fc3(x))
x = torch.nn.functional.relu(self.fc4(x))
x = torch.nn.functional.log_softmax(self.fc5(x), dim=1)#softmax归一化
return x
def get_data_loader(is_train):#读取数据
to_tensor = transforms.Compose([transforms.ToTensor()])
data_set = MNIST("", is_train, transform=to_tensor, download=True)#下载训练集 is_train 是否是训练集
return DataLoader(data_set, batch_size=15, shuffle=True) #shuffle,顺序打乱
def evaluate(test_data, net):#预测评估
correctnub = 0#对的数量
totalnub = 0#总的
with torch.no_grad():
for (x, y) in test_data:
outputs = net.forward(x.view(-1, 28 * 28))
for i, output in enumerate(outputs):
if torch.argmax(output) == y[i]:#torch.argmax()数据概率最大索引值
correctnub += 1
totalnub += 1
return correctnub / totalnub
def main():
train_data = get_data_loader(is_train=True)#训练集
test_data = get_data_loader(is_train=False)#测试集
net = Net()
print("初始的精确度:", evaluate(test_data, net))
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)#Adam优化器 梯度
for epoch in range(1):#进行一次迭代
for (x, y) in train_data:
net.zero_grad()#用于清空优化器中的梯度,防止对下一次梯度下降产生影响
output = net.forward(x.view(-1, 28 * 28))#将点阵转化为一维数组,方便下一步搞神经网络运算
loss = torch.nn.functional.nll_loss(output, y)#计算损失函数
loss.backward()#反向传播算法
optimizer.step()#基于反向传播算法调整神经网络参数
print("epoch", epoch, "accuracy:", evaluate(test_data, net))
for (n, (x, _)) in enumerate(test_data):
if n > 3:
break
predict = torch.argmax(net.forward(x[0].view(-1, 28 * 28)))#预测结果
plt.figure(n)
plt.imshow(x[0].view(28, 28))
plt.title("prediction: " + str(int(predict)))
plt.show()
if __name__ == "__main__":
main()
其中我们主要是做特征工程来提取特征(这也是深度学习的牛逼之处,他可以自己选择特征来学习,区别于机器学习的人工提取特征)
好,废话不多说,直接讲案例
我们先写训练集图片数据加载,然后再写一个前向传播的函数,然后再写一个预测评估函数,那反向传播哪?答:库里有,直接哪来用进行,下边两行直接调用进行。现在我们已经吧问题分解为数据加载,前向传播的函数,预测评估函数这几个部分了,具体实现过程在上边代码有不多少说。
loss.backward()#反向传播算法
optimizer.step()#基于反向传播算法调整神经网络参数
我们主要看看,如何将这些部分链接起来
train_data = get_data_loader(is_train=True)#训练集
test_data = get_data_loader(is_train=False)#测试集
net = Net()
print("初始的精确度:", evaluate(test_data, net))
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)#Adam优化器 梯度
for epoch in range(1):#进行一次迭代
for (x, y) in train_data:
net.zero_grad()#用于清空优化器中的梯度,防止对下一次梯度下降产生影响
output = net.forward(x.view(-1, 28 * 28))#将点阵转化为一维数组,方便下一步搞神经网络运算
loss = torch.nn.functional.nll_loss(output, y)#计算损失函数
loss.backward()#反向传播算法
optimizer.step()#基于反向传播算法调整神经网络参数
print("epoch", epoch, "accuracy:", evaluate(test_data, net))
for (n, (x, _)) in enumerate(test_data):
if n > 3:
break
predict = torch.argmax(net.forward(x[0].view(-1, 28 * 28)))#预测结果
plt.figure(n)
plt.imshow(x[0].view(28, 28))
plt.title("prediction: " + str(int(predict)))
plt.show()
注意 optimizer = torch.optim.Adam(net.parameters(), lr=0.001)#这一行是用来构造Adam算法优化器的 是我们梯度下降和反向传播的基础
t