mnist数据集

import tensorflow as  tf
import numpy as np
import matplotlib.pyplot as plt

笔记:

下面的这个x_train, x_test = x_train / 255.0, x_test / 255.0  这个归一化操作非常重要 在单层神经网络的训练手写数字识别的时候 
我们习惯使用softmax分类函数  这没问题 但是 要考虑一个文艺  softmax的计算是指数形式的  在没有归一化之前 : c是原始数据  d是归一化的
c = np.array(tf.cast(c,dtype=tf.float32)).reshape(1,784)
d = np.array(tf.cast(d,dtype=tf.float32)).reshape(1,784)
y1 = tf.matmul(c,w1)+ b1
print(y1)
y1 = tf.nn.softmax(y1)
print(y1)

y2 = tf.matmul(d,w1)+ b1
print(y2)
y1 = tf.nn.softmax(y2)
print(y2)
执行这段代码 输出之后 你会明显的发现 :


tf.Tensor(
[[ 327.17645  -424.2321    211.14766   624.6971   -870.94885   795.67725
  -119.88079   101.743286   53.492374  -17.998362]], shape=(1, 10), dtype=float32)
tf.Tensor([[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)
tf.Tensor(
[[ 1.1203     -1.5452155   0.70625913  2.2565136  -3.322827    3.208177
  -0.35524258  0.5323045  -0.05956426 -0.05602657]], shape=(1, 10), dtype=float32)
tf.Tensor(
[[ 1.1203     -1.5452155   0.70625913  2.2565136  -3.322827    3.208177
  -0.35524258  0.5323045  -0.05956426 -0.05602657]], shape=(1, 10), dtype=float32)
softmax本来是个概率分布函数  但是如果不进行数据归一化 就会产生一个问题 其中有个数值较大 
经过softmax进行计算之后 就会出现一个极大的数据  别的数据相对这个数据都非常小了  就会造成一个概率值为1  其余基本为0的问题  这样就会导致
梯度坏死  也就是梯度消失吧 我猜的 
#可以认为这个mnist是个py文件吗  还有为啥(x_train,y_train) = mnist.load_data() 得到的x_train就没有相应的shape属性呢
mnist = tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
c = x_train[0]
x_train, x_test = x_train / 255.0, x_test / 255.0

plt.imshow(X= x_train[0])
plt.show()
#注意需要加上 后缀名
a = plt.imread('timg.jpg')
plt.imshow(X=a)
print(y_test.shape)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AUYBAT9j-1588224104828)(output_2_0.png)]

(10000,)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-faBzWoTH-1588224104846)(output_2_2.png)]

上面进行了数据的读取 我们可以看到数据的形式 &nbsp 是一个numpy数组的形式 我们需要对数据进行一些基本的处理 比如匹配标签 打乱数据集的顺序 其实这个手写数字集的顺序不需要打乱 本身就是乱序

使用函数tf.convert_to_tensor(img.eval())将numpy数组转换成张量对象。 
送入神经网络训练的只能是张量  Tensor  Tnesor也具有numpy数据所具备的基本属性  但是Tensor不具备numpy数组的 numpy.flags这个属性
有个重要的问题 就是tensorflow程序的执行流程是什么样的呀
使用type()函数看一个东西是ndarray 还是Tensor
也可以使用使用tf.is_tensor()查看对象是否是一个张量
虽然在搞这个入门级别的东西 但是还是遇到很多BUG  也算费尽心思才解决吧 
首先经过(x_train,y_train),(x_test,y_test) = mnist.load_data() 读入的x_train()是一个ndarray  他自然具有ndarray的一切属性  
常见的ndarray的属性:
ndarray.ndim    秩,即轴的数量或维度的数量
ndarray.shape    数组的维度,对于矩阵,n 行 m 列
ndarray.size    数组元素的总个数,相当于 .shape 中 n*m 的值
ndarray.dtype    ndarray 对象的元素类型
ndarray.itemsize   ndarray 对象中每个元素的大小,以字节为单位
ndarray.flags    ndarray 对象的内存信息
ndarray.real    ndarray元素的实部
ndarray.imag    ndarray 元素的虚部
ndarray.data    包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。
这里面 有个属性是ndarray.flags 这个ndarray的属性说的是对象的内存信息  
使用print(x_train.flags)
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : False
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
属性                 描述
C_CONTIGUOUS (C)    数据是在一个单一的C风格的连续段中
F_CONTIGUOUS (F)    数据是在一个单一的Fortran风格的连续段中
OWNDATA (O)    数组拥有它所使用的内存或从另一个对象中借用它
WRITEABLE (W)    数据区域可以被写入,将该值设置为 False,则数据为只读
ALIGNED (A)    数据和所有元素都适当地对齐到硬件上
UPDATEIFCOPY (U)    这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新
我们读出的数据 根据输出的这个属性 我们知道他是只读的所以我们不能对他进行写的操作  但是有个小问题 那就是我觉得np.random.shuffle()这个
乱序函数 并没有对他进行写操作啊  知识乱序一下啊  不过我看了一下 其他代码中shuffle操作的ndarray对象中的flags的属性 确实是可写的 暂时就这     样记下吧!

哎  为自己的知识储备不足感到担忧啊 
#那就继续先熟悉一下 数据集乱序
x_train = np.array(x_train)
y_train = np.array(y_train)
np.random.seed(123)
np.random.shuffle(x_train)
np.random.seed(123)
np.random.shuffle(y_train)
tf.random.set_seed(seed=123)
plt.imshow(X=x_train[0].reshape(28,28))
plt.show()

#进行一下数据转换 
x_train=tf.cast(x_train,tf.float32)
y_train = tf.cast(y_train,tf.int32)
x_test = tf.cast(x_test,tf.float32)
y_test = tf.cast(y_test,tf.int32)

x_train = np.reshape(x_train,newshape=(60000,784))
x_test = np.reshape(x_test,newshape=(10000,784))

# 将x_train 和y_train进行配对 并且设置每次喂入神经网络的数据
x_train_db = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(32)
x_test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(32)
print(y_test.shape)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zCRZDxQ-1588224104850)(output_4_0.png)]

(10000,)

构造神经网络的参数:

首先 先试用两层的神经网络训练一下试试  单层的话  784的输入 也就是需要784个隐藏神经元   10分类输出 输出需要10个神经元  类似这种 
但是我们最后是10分类 也就是10个神经元

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YcB79DVc-1588224104852)(attachment:image.png)]

# w1 = tf.Variable(np.random.normal(size=(784,10)),dtype = tf.float32)
# b1 = tf.Variable(np.random.randn(10),dtype = tf.float32)
w1 = tf.Variable(tf.random.truncated_normal([784, 100], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([100], stddev=0.1, seed=1))
w2 = tf.Variable(np.random.normal(size=(100,10)),dtype = tf.float32)
b2 = tf.Variable(np.random.randn(10),dtype = tf.float32)
epoch = 100
LR_BASE = 0.2
LR_DECRY = 0.99
LR_STEP = 1
#定义两个个空的列表 用来存储每次epoch之后的损失值 和 测试的精度
loss_epoch = []
acc_epoch = [] 
test_acc =[]
acc=0.0
loss=0
print(y_train)
tf.Tensor([4 9 8 ... 0 9 4], shape=(60000,), dtype=int32)

这里面有个东西快把我搞死了

损失函数这个东西 一开使用的最开始的那个MSE  效果还可以  后来感觉在这种多分类单标签的分类中 使用交叉熵损失函数会更好一些 
于是乎 使用了  tf.nn.softmax_cross_entropy_with_logits()  这个函数已经过时了  卧槽 反正就是不要使用 坚决不要使用 不能用

在使用tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels)语句时产生。原因是logits和labels在使用时有labels应该少一维的限制。
这个函数的 labels 与前面那个函数不同,这个函数的 labels 是一个索引数值,给出的是这个图片具体属于哪类,而不是一个概率分布。
labels 的 shape 一般都是 [batchsize] ,而 logits 与前面一样,它的 shape 是 [batchsize, numberClass]

 y_ = (tf.one_hot(y_train,depth=10))这个独热码的转换会把数据扩充一个维度 需要注意
#训练部分
for epoch in range(10):
    lr = LR_BASE * LR_DECRY **  (epoch/LR_STEP)
    for step,(x_train,y_train) in enumerate(x_train_db):
        with tf.GradientTape() as  Tape:
            y = tf.matmul(x_train,w1)+ b1
            y = tf.nn.relu(y)
            y = tf.matmul(y,w2) + b2
            y = tf.nn.softmax(y)
            y_ = (tf.one_hot(y_train,depth=10))
            #loss_mse = tf.reduce_mean(tf.square(y-y_))
            loss_mse = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y_,axis=1),logits=y))
            loss+=loss_mse.numpy()
        grad = Tape.gradient(loss_mse,[w1,b1,w2,b2])
        #print(grad)
        w1.assign_sub(lr*grad[0])
        b1.assign_sub(lr*grad[1])
        w2.assign_sub(lr*grad[2])
        b2.assign_sub(lr*grad[3])
        correct = tf.cast(tf.equal(tf.argmax(y,axis=1),tf.argmax(y_,axis=1)),dtype=tf.int32)
        acc = tf.cast(tf.reduce_sum(correct),dtype=tf.float32)/32.0
    loss_epoch.append(loss_mse)   
    if(epoch%1==0):
        print("after {} 后: loss:{}  acc:{}".format(epoch,loss,acc))
    loss = 0
     #测试部分
    total_correct, total_number = 0, 0
    for x_test,y_test in x_test_db:
        y = tf.matmul(x_test,w1)+b1
        y = tf.nn.relu(y)
        y = tf.matmul(y,w2)+b2
        y = tf.nn.softmax(y)
        pred = tf.argmax(y,axis=1)
        pred = tf.cast(pred,dtype=y_test.dtype)
        correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32)
        correct = tf.reduce_sum(correct)
        total_correct+=int(correct)
        total_number += x_test.shape[0]
    acc = total_correct / total_number
    test_acc.append(acc)
    if(epoch%1==0):
        print("after {} Test_acc:{}".format(epoch,acc))
        print("--------------------------")
        
after 0 后: loss:7.956651736908952  acc:0.96875
after 0 Test_acc:0.9591
--------------------------
after 1 后: loss:7.49035571733134  acc:0.96875
after 1 Test_acc:0.9598
--------------------------
after 2 后: loss:7.089186773868278  acc:0.96875
after 2 Test_acc:0.9606
--------------------------
after 3 后: loss:6.745345288035651  acc:0.96875
after 3 Test_acc:0.9614
--------------------------
after 4 后: loss:6.430445950237981  acc:0.96875
after 4 Test_acc:0.9619
--------------------------
after 5 后: loss:6.144285260919105  acc:0.96875
after 5 Test_acc:0.9628
--------------------------
after 6 后: loss:5.890222105777411  acc:0.96875
after 6 Test_acc:0.9629
--------------------------
after 7 后: loss:5.658413398420862  acc:0.96875
after 7 Test_acc:0.9638
--------------------------
after 8 后: loss:5.450259750040686  acc:0.96875
after 8 Test_acc:0.9643
--------------------------
after 9 后: loss:5.264862050912939  acc:0.96875
after 9 Test_acc:0.9652
--------------------------
import tensorflow as tf

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

model.fit(x_train, y_train, batch_size=32, epochs=10, validation_data=(x_test, y_test), validation_freq=1)
model.summary()
WARNING:tensorflow:From D:\Anaconde\A\envs\tensorflow2_0\lib\site-packages\tensorflow\python\ops\math_grad.py:1250: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] - 2s 37us/sample - loss: 0.2593 - sparse_categorical_accuracy: 0.9266 - val_loss: 0.1341 - val_sparse_categorical_accuracy: 0.9605
Epoch 2/10
60000/60000 [==============================] - 2s 32us/sample - loss: 0.1107 - sparse_categorical_accuracy: 0.9676 - val_loss: 0.1011 - val_sparse_categorical_accuracy: 0.9688
Epoch 3/10
60000/60000 [==============================] - 2s 34us/sample - loss: 0.0755 - sparse_categorical_accuracy: 0.9774 - val_loss: 0.0927 - val_sparse_categorical_accuracy: 0.9708
Epoch 4/10
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0579 - sparse_categorical_accuracy: 0.9825 - val_loss: 0.0777 - val_sparse_categorical_accuracy: 0.9770
Epoch 5/10
60000/60000 [==============================] - 2s 32us/sample - loss: 0.0438 - sparse_categorical_accuracy: 0.9867 - val_loss: 0.0788 - val_sparse_categorical_accuracy: 0.9750
Epoch 6/10
60000/60000 [==============================] - 2s 31us/sample - loss: 0.0350 - sparse_categorical_accuracy: 0.9893 - val_loss: 0.0742 - val_sparse_categorical_accuracy: 0.9762
Epoch 7/10
60000/60000 [==============================] - 2s 32us/sample - loss: 0.0285 - sparse_categorical_accuracy: 0.9912 - val_loss: 0.0703 - val_sparse_categorical_accuracy: 0.9783
Epoch 8/10
60000/60000 [==============================] - 2s 32us/sample - loss: 0.0216 - sparse_categorical_accuracy: 0.9934 - val_loss: 0.0759 - val_sparse_categorical_accuracy: 0.9780
Epoch 9/10
60000/60000 [==============================] - 2s 34us/sample - loss: 0.0191 - sparse_categorical_accuracy: 0.9941 - val_loss: 0.0839 - val_sparse_categorical_accuracy: 0.9768
Epoch 10/10
60000/60000 [==============================] - 2s 31us/sample - loss: 0.0170 - sparse_categorical_accuracy: 0.9945 - val_loss: 0.0815 - val_sparse_categorical_accuracy: 0.9785
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            multiple                  0         
_________________________________________________________________
dense (Dense)                multiple                  100480    
_________________________________________________________________
dense_1 (Dense)              multiple                  1290      
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________

训练过程笔记:

一开始有个问题我一直没有明白 记录在这里:
问题:举例来说  手写数字识别是一个10分类单标签的任务 我们假设一次喂入神经网络的参数是32*784 那么经过第一层全连接得到32*10的一个矩阵
这个矩阵每一行中的数据代表了这个数字是几的可能性  y_train经过one_hot编码转换后 变成32*10的形状
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值