发新帖

求助,MNIST手写数字识别的问题

[复制链接]
118 1
本帖最后由 leeco 于 2019-11-1 13:15 编辑

我先写了一个没有隐层的,只有输入输出层,相当于线性回归的模型。获得了0.8+的预测正确率,看上去还挺正常。
然后我尝试在中间添加一个隐层,结果训练到后面loss已经不再下降的时候只获得了0.1167的预测正确率,所有预测结果似乎都会返回7。
我看了几遍也没有看出问题,请大神指导一下,我觉得主要的问题应该在构建模型的步骤里面
我在附件里上传了.ipynb文件,去jupyter看更方便些。

  1. #!/usr/bin/env python
  2. # coding: utf-8

  3. # In[6]:


  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. import pandas as pd
  7. # import tensorflow as tf
  8. import tensorflow.compat.v1 as tf
  9. # from tensorflow.examples.tutorials.mnist import input_data
  10. from keras.datasets import mnist
  11. from sklearn.preprocessing import OneHotEncoder
  12. from sklearn.model_selection import train_test_split
  13. from sklearn.utils import shuffle


  14. # In[2]:


  15. (x_trainval, y_trainval), (x_test, y_test) = mnist.load_data()
  16. x_train, x_val, y_train, y_val = train_test_split(x_trainval, y_trainval, stratify=y_trainval, test_size=0.1, random_state=0 )

  17. # 对y进行One-Hot编码
  18. onehot = OneHotEncoder(categories='auto').fit(np.array(range(10)).reshape(-1,1))
  19. X_train = x_train.reshape(-1, 28*28)
  20. Y_train = onehot.transform(y_train.reshape(-1,1)).A
  21. X_val = x_val.reshape(-1, 28*28)
  22. Y_val = onehot.transform(y_val.reshape(-1,1)).A
  23. X_test = x_test.reshape(-1, 28*28)
  24. Y_test = onehot.transform(y_test.reshape(-1,1)).A

  25. print(X_train.shape)
  26. print(X_val.shape)
  27. print(X_test.shape)

  28. fig, axes = plt.subplots(2, 5, subplot_kw={'xticks':(), 'yticks':()})
  29. for (i, ax) in zip(range(10), axes.ravel()):
  30.     ax.imshow(X_train[i].reshape((28,28)))
  31. print(y_train[0:10])


  32. # In[3]:


  33. train_epochs = 30
  34. batch_size = 100
  35. total_batch = (X_train.shape[0] + batch_size - 1) // batch_size
  36. display_step = 1
  37. learning_rate = 0.01

  38. def fetch_batch(batch):
  39.     global X_train, Y_train, batch_size
  40.     return X_train[batch_size*batch: min(batch_size*batch+batch_size,X_train.shape[0]) ], Y_train[batch_size*batch: min(batch_size*batch+batch_size,Y_train.shape[0] )]


  41. # In[4]:


  42. # 构建模型

  43. H1_NN = 100 # 第一隐层神经元数量

  44. g = tf.Graph()
  45. with g.as_default():
  46.     x = tf.placeholder(tf.float32, [None, 28*28], name="X")
  47.     y = tf.placeholder(tf.float32, [None, 10], name="Y")
  48.    
  49.     #''' #解开前面的注释
  50.     W1 = tf.Variable(tf.truncated_normal([28*28, H1_NN]), name="W1")
  51.     b1 = tf.Variable(tf.zeros([H1_NN]), name="b1")
  52.     Y1 = tf.nn.relu(tf.matmul(x,W1)+b1) # 外面套一个ReLU激活函数
  53.    
  54.     W2 = tf.Variable(tf.truncated_normal([H1_NN, 10]), name="W2")
  55.     b2 = tf.Variable(tf.zeros([10]), name="b2")
  56.     forward = tf.matmul(Y1,W2)+b2
  57.     '''
  58.     W = tf.Variable(tf.truncated_normal([28*28, 10]), name="W")
  59.     b = tf.Variable(tf.zeros([10]), name="b")
  60.     forward = tf.matmul(x,W)+b
  61.     ''' # 本行前面加上#
  62.    
  63.     # 这时pred是概率向量,每个分量取值0~1,求和为1,分布代表各个数字的预测值
  64.     pred = tf.nn.softmax(forward)
  65.    
  66.     # 损失函数
  67.     loss_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=forward, labels=y))
  68.    
  69.     # 优化器
  70.     optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_func)
  71.    
  72.     correct_pred = tf.equal( tf.argmax(pred, 1), tf.argmax(y, 1) )
  73.     accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32) )


  74. # In[5]:


  75. # 训练模型
  76. with tf.Session(graph = g) as sess:
  77.     sess.run(tf.global_variables_initializer())

  78.     for epoch in range(train_epochs):
  79.         for batch in range(total_batch):
  80.             xs, ys = fetch_batch(batch)
  81.             sess.run([optimizer], feed_dict={x:xs, y:ys})
  82.         shuffle(X_train, Y_train, random_state=0)

  83.         if (epoch+1)%display_step==0:
  84.             loss, acc = sess.run([loss_func, accuracy], feed_dict={x:X_val, y:Y_val} )
  85.             print(f"Epoch:{epoch+1:3d} Loss:{loss:.4f} Acc:{acc:.4f}" )

  86.     acc = sess.run(accuracy, feed_dict={x:X_test, y:Y_test})
  87.     print(f"Test Acc:{acc:.4f}")

  88.     fig, axes = plt.subplots(1, 5, subplot_kw={'xticks':(), 'yticks':()})
  89.     for (i, ax) in zip([123,456,234,564,12], axes.ravel()):
  90.         prediction = np.argmax(sess.run(pred, feed_dict={x:[X_test[i]]}))
  91.         ax.set_title(f"pre:{prediction} lab:{y_test[i]}" )
  92.         ax.imshow(X_test[i].reshape((28,28)))

复制代码



https://www.tensorflowers.cn/forum.php?mod=attachment&aid=MzU2NXwwODRhYmI3ODFmMDczMjZlNGNhZTVlZTAwZmQ2Y2Y3Y3wxNTc0MzE2NTc2&request=yes&_f=.rar

我知道答案 回答被采纳将会获得10 金币 + 5 金币 已有1人回答

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
本楼点评(0) 收起

精彩评论1

leeco  TF荚荚  发表于 2019-11-1 13:13:50 | 显示全部楼层
自问自答吧,已经解决了,我看的教程里面是通过
from tensorflow.examples.tutorials.mnist import input_data
来载入的MNIST手写数字的数据,但我在练习时发现无法通过此方式载入,可能是TF2.0版本的载入方式变了或者别的原因,无论怎样,我使用的是keras里的MNIST数据
from keras.datasets import mnist
这里就是问题的根源,虽然我后面手动对数据进行了处理,包括对label进行One-Hot编码,把图片特征reshape成1维等,但是我忘记查看像素编码是0~1还是0~255了,而keras里面正好是0~255,在开始的逻辑回归时对缩放是不敏感的,而到了神经网络就对缩放敏感了,
所以解决方式就是把特征除以255,缩放至0~1。


本楼点评(0) 收起
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

主题

帖子

3

积分
快速回复 返回顶部 返回列表