这几天看沐神的课程,试试手写体识别预测的模型,记录一下
1、加载数据集
from mxnet import nd,autograd,gluon,init
from mxnet.gluon import loss,nn
import mxnet as mx
batch_size=128 #设置读取批量
train_data=gluon.data.vision.MNIST(train=True) #生成训练数据
test_data=gluon.data.vision.MNIST(train=True)#生成测试数据
transform=gluon.data.vision.transforms.ToTensor()#格式
train_iter=gluon.data.DataLoader(train_data.transform_first(transform),shuffle=True,
batch_size=batch_size)#生成训练数据迭代器
test_iter=gluon.data.DataLoader(test_data.transform_first(transform),shuffle=False,
batch_size=batch_size)#生成测试数据迭代器
2、构建模型
目前还没学到卷积那里,先全连接凑合(捂脸)
model=nn.Sequential()
model.add(nn.Dense(256,activation='relu'))
model.add(nn.Dense(64,activation='relu'))
model.add(nn.Dense(10))
model.initialize()
mine_loss=loss.SoftmaxCrossEntropyLoss()
trainer=gluon.Trainer(model.collect_params(),optimizer='sgd',
optimizer_params={"learning_rate":0.03})
3、定义准确度和评估函数
def accuracy(yhat,y):
return nd.mean(yhat.argmax(axis=1)==y).asscalar()
#yhat.argmax(axis=1)这个地方实际上就是预测值和真实值的对比,后面在做预测的时候参照这个地方
def evaluate_accuracy(data_iter,model):
acc=0.
for data,label in data_iter:
label=label.astype('float32')
output=model(data)
acc += accuracy(output,label)
return acc
4、开始训练
for epoch in range(5):
train_acc=0
train_loss=0
for data,label in train_iter:
with autograd.record():
output=model(data)
my_loss=mine_loss(output,label)
label=label.astype('float32')
my_loss.backward()
trainer.step(batch_size)
train_acc += accuracy(output,label)
train_loss += nd.mean(my_loss).asscalar()
test_acc = evaluate_accuracy(test_iter,model)
print(F'epoch:{epoch+1},loss:{train_loss/len(train_iter)},train_acc:{train_acc/len(train_iter)},test_acc:{test_acc/len(test_iter)}')
训练结果如下:
还凑合,以后学到卷积的时候会更好
5、做预测
因为为了显示单个图片,我把batch_size改为了1,如果不变的话就是128,不太能达到讲述效果
from matplotlib import pyplot as plt
import numpy as np
test_iter_aa=gluon.data.DataLoader(test_data.transform_first(transform),shuffle=False,
batch_size=1)
for data,label in test_iter_aa:
plt.imshow(data.reshape((28,28)).asnumpy())
#这里在进入网络之前data.shape的输出结果是(1,1,28,28)
#data的type是 mxnet.ndarray.ndarray.NDArray
#到下面做自己下载图片的预测时,也是要跟这个保持一致,否则会报“shape inconsistent”这样的错误
output=model(data)
pre=output.argmax(axis=1)
print(pre)
print(label)
break
结果如下
最后,这是人家自己带的数据集,我们可以试试自己下载的图片预测结果如何
-
通过PIL.Image包导入我们自己下载的图片,并将其转换为灰度图,以及更改图片(resize图片的目的就是为了适应模型)
这个是下载的图片
这个是转换后的图片
-
转换数据类型,此时我们通过PIL包导入的图片肯定不是mxnet.ndarray.ndarray.NDArray,因此传入模型时要转化变量类型
-
数据处理,上面我们已经将图片转换成数组,为了传入模型,还要将图片astype(‘float32’),
下面是该部分代码
from PIL import Image
import numpy as np
import mxnet as mx
# 1、导图+改变图形
img=Image.open('D:/DYM/pictures/common/test3.jpg').convert('L').resize((28,28))
# 2、更改变量类型
img=mx.nd.array(img)
# 3、数据处理
img=img.reshape((1,1,28,28))
img=255-img.astype('float32')
# 4、做预测
output=model(img)
pre=output.argmax(axis=1)
print(pre)
结果如下(还不错)
最后,欢迎各位指导交流