使用Tensorflow 编写CNN进行手写数字识别准确率上不去

#导入
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential

#数据加载
(train_images,train_labels),(test_images,test_labels)=mnist.load_data()
#卷积输入要求:H-图片数、N-图片高、W-图片宽、C-图片通道
#数据处理
train_images=tf.reshape(train_images,(train_images.shape[0],train_images.shape[1],train_images.shape[2],1))
test_images=tf.reshape(test_images,(test_images.shape[0],test_images.shape[1],test_images.shape[2],1))
train_labels=tf.keras.utils.to_categorical(train_labels,10)
test_labels=tf.keras.utils.to_categorical(test_labels,10)
#构建模型
net=Sequential([
    #卷积层,6个5*5的卷积核,激活函数是relu,没张图片是28*28*1
    tf.keras.layers.Conv2D(filters=6,kernel_size=5,activation='relu',input_shape=(28,28,1)),
    #最大池化
    tf.keras.layers.MaxPool2D(pool_size=2,strides=2),
    #卷积层:16个5*5的卷积核,激活函数是relu
    tf.keras.layers.Conv2D(filters=16,kernel_size=5,activation='relu'),
    #最大池化
    tf.keras.layers.MaxPool2D(pool_size=2,strides=2),
    #维度调整为1维数据
    tf.keras.layers.Flatten(),
    #全卷积层,激活relu
    tf.keras.layers.Dense(120,activation='relu'),
    #全卷积层,激活relu
    tf.keras.layers.Dense(84,activation='relu'),
    #全卷积层,激活relu
    tf.keras.layers.Dense(10,activation='softmax')
])

#模型编译
net.compile(loss=tf.keras.losses.categorical_crossentropy,
            metrics=tf.keras.metrics.Accuracy(),
            optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
# net.compile(loss='sparse_categorical_crossentropy',metrics=['accuracy'],optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
#标签值热编码后loss用categorical_crossentropy,如果没有热编码就用sparse_categorical_crossentropy

#模型训练
net.fit(train_images,train_labels,epochs=4,batch_size=128,validation_split=0.1,verbose=1)

#模型评估
score=net.evaluate(test_images,test_labels,verbose=1)
print(score[1])

结果:
在这里插入图片描述
这里检查了很久代码都没有问题,后来找到了原因是因为Keras的版本问题,就是在model编译部分,Keras和TensorFlow拆开以后,有的版本不支持调用方法,只支持使用字符串调用,其中优化器是可以调用方法的,另外的loss和metrics就只能是通过字符串使用,否则就是表面上没有语法错误,实际上什么也没有学到

#导入
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential

#数据加载
(train_images,train_labels),(test_images,test_labels)=mnist.load_data()
#卷积输入要求:H-图片数、N-图片高、W-图片宽、C-图片通道
#数据处理
train_images=tf.reshape(train_images,(train_images.shape[0],train_images.shape[1],train_images.shape[2],1))
test_images=tf.reshape(test_images,(test_images.shape[0],test_images.shape[1],test_images.shape[2],1))

#构建模型
net=Sequential([
    #卷积层,6个5*5的卷积核,激活函数是relu,没张图片是28*28*1
    tf.keras.layers.Conv2D(filters=6,kernel_size=5,activation='relu',input_shape=(28,28,1)),
    #最大池化
    tf.keras.layers.MaxPool2D(pool_size=2,strides=2),
    #卷积层:16个5*5的卷积核,激活函数是relu
    tf.keras.layers.Conv2D(filters=16,kernel_size=5,activation='relu'),
    #最大池化
    tf.keras.layers.MaxPool2D(pool_size=2,strides=2),
    #维度调整为1维数据
    tf.keras.layers.Flatten(),
    #全卷积层,激活relu
    tf.keras.layers.Dense(120,activation='relu'),
    #全卷积层,激活relu
    tf.keras.layers.Dense(84,activation='relu'),
    #全卷积层,激活relu
    tf.keras.layers.Dense(10,activation='softmax')
])

#模型编译
# net.compile(loss=tf.keras.losses.sparse_categorical_crossentropy,
#             metrics=tf.keras.metrics.Accuracy(),
#             optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
net.compile(loss='sparse_categorical_crossentropy',metrics=['accuracy'],optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
#标签值热编码后loss用categorical_crossentropy,如果没有热编码就用sparse_categorical_crossentropy

#模型训练
net.fit(train_images,train_labels,epochs=10,batch_size=128,validation_split=0.1,verbose=1)

#模型评估
score=net.evaluate(test_images,test_labels,verbose=1)
print(score[1])

以上是修正过的代码,下面是运行结果:
在这里插入图片描述
注:
要注意热编码跟loss的对应问题,categorical_crossentropy和sparse_categorical_crossentropy都是交叉熵损失函数,它们的数学意义相同,区别仅在于适用于不同的类别标签编码格式。

当输入数据的类别标签采用独热编码(OneHot Encoding)格式时,模型应采用 categorical_crossentropy 损失函数;当输入数据的类别标签采用序号编码(Label Encoding)格式时(例如手写数字识别的0、1、2),模型应采用 sparse_categorical_crossentropy 损失函数。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泡沫不是茶香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值