训练数据:https://pjreddie.com/media/files/mnist_train.csv
测试数据:https://pjreddie.com/media/files/mnist_test.csv
# 加载数据文件
from google.colab import drive
drive.mount('./mount')
class Classifier(nn.Module):
def __init__(self):
# 初始化PyTorch父类
super().__init__()
# 定义神经网络层
self.model = nn.Sequential(
nn.Linear(784, 200),
nn.Sigmoid(),
nn.Linear(200, 10),
nn.Sigmoid()
)
# 创建损失函数
self.loss_function = nn.MSELoss()
# 创建优化器,使用简单的梯度下降
self.optimiser = torch.optim.SGD(self.parameters(), lr=0.01)
def forward(self, inputs):
# 直接运行模型
return self.model(inputs)
def train(self, inputs, targets):
# 计算网络的输出值
outputs = self.forward(inputs)
# 计算损失值
loss = self.loss_function(outputs, targets)
# 梯度归零,反向传播,并更新权重
self.optimiser.zero_grad()
loss.backward()
self.optimiser.step()
# 记录训练进展的计数器和列表
self.counter = 0
self.progress = []
# 增加一次计数器的值,每隔10个训练样本将损失值添加进列表的末尾
self.counter += 1
if (self.counter % 10 == 0):
self.progress.append(loss.item())
pass
class MnistDataset(Dataset):
def __init__(self, csv_file):
self.data_df = pandas.read_csv(csv_file, header=None)
pass
def __len__(self):
return len(self.data_df)
def __getitem__(self, index):
# 目标图像(标签)
label = self.data_df.iloc[index, 0]
target = torch.zeros((10)) # 创建一个维度为10的张量变量,神经网络的预期输出
target[label] = 1.0 # 与标签相对应的张量是1,其他都是0
# 图像数据,取值范围是0~255,标准化为0~1
image_values = torch.FloatTensor(self.data_df.iloc
[index, 1:].values) / 255.0
# 返回标签、图像数据张量以及目标张量
return label, image_values, target
pass
def plot_image(self, index):
arr = self.data_df.iloc[index,1:].values.reshape(28,28)
plt.title("label = " + str(self.data_df.iloc[index,0]))
plt.imshow(arr, interpolation='none', cmap='Blues')
pass
%%time
# 创建神经网络
C = Classifier()
# 在MNIST数据集训练神经网络
epochs = 3
for i in range(epochs):
print('training epoch', i+1, "of", epochs)
for label, image_data_tensor, target_tensor in mnist_dataset:
C.train(image_data_tensor, target_tensor)
pass
pass
# 定义神经网络层
self.model = nn.Sequential(
nn.Linear(784, 200),
# nn.Sigmoid(),
nn.LeakyReLU(0.02), # 0.02是函数左半边的梯度
nn.Linear(200, 10),
# nn.Sigmoid()
nn.LeakyReLU(0.02)
)