《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1

  • Python版本: Python3.x
  • 运行平台: Windows
  • 参考资料:吴恩达
  • IDE: jupyter
  • 转载请标明出处:https://blog.csdn.net/tian121381/category_9748511.html
  • 资料下载,提取码:nw0v

    目录

    • 一、前言
    • 二、相当于Hello World的神经网络
        • 编辑定义神经网络
        • 优化器和代价函数定义
        • 提供数据
        • 训练神经网络
        • 课后小练习
    • 三、 较复杂的神经网络
        • 数据处理
        • 模型构建
        • 预测
        • 思考
        • 课后小练习 ---自写哈
          • TensorFlow回调函数:tf.keras.callbacks.Callback
    • 四、卷积神经网络---tensorflow2.0
        • 细讲代码
        • 卷积和池化层的可视化
        • 思考
    • 五、结语

一、前言

机器学习中的SVM其实是鸽了,(●’◡’●)。因为公式太难打了,有时间再补上吧(如需要SVM的相关代码,可以评论发邮箱)。现在开新坑,tensorflow2.0的使用。主要是以实例来讲解。这部分需要深度学习/机器学习的基础。
主要的讲解方法是写一个例子,详细讲解。然后给出一个练习,你们自写后再看我给的参考代码。(ง •_•)ง

二、相当于Hello World的神经网络

我们开始先来一个简单的网络,自己写一个线性的数据,看看我们在输入数据时,能不能给出我们正确的结果呢?
首先导入相关包。

import tensorflow as tf
import numpy as np
from tensorflow import keras

编辑定义神经网络

我们将创建最简单的神经网络。 它具有1层,并且该层具有1个神经元(一个单元),并且其输入形状仅为1值。

model = tf.keras.Sequential(  [  keras.layers.Dense(units=1,input_shape = [1])])

优化器和代价函数定义

现在,我们编译神经网络。这样做时,我们必须指定两个函数,一个损失和一个优化器。 如果已经看过很多用于机器学习的数学,这就是通常使用的地方,但是在这种情况下,它可以很好地封装在您的函数中。但是这里发生了什么?让我们解释一下… 我们知道在函数中,数字之间的关系为y = 2x-1。 当计算机尝试“学习”时,会做出猜测…也许y = 10x + 10。损失功能根据已知的正确答案来衡量猜测的答案,并衡量其执行的好坏程度。 然后,它使用OPTIMIZER函数进行另一个猜测。基于损失函数的运行方式,它将尝试使损失最小化。到那时,也许会得出类似y = 5x + 5的结果,虽然仍然很糟糕,但更接近正确的结果(即损失更低) 它将重复此操作,您将很快看到epochs的数量。但首先,这是我们告诉它的方法,即对损失使用“均方误差”,对优化器使用“随机梯度下降”。不需要了解它们的数学原理,但是可以看到它们起作用了! 如果有时间,多了解以下针对不同情况的不同且适当的损失和优化器功能。 下面为随机梯度下降,均值方差。

model.compile(optimizer="sgd",loss="mean_squared_error")

提供数据

接下来,输入一些数据。在这种情况下,我们取6个xs和6个ys。 您会看到它们之间的关系是y = 2x-1,因此x = -1,y = -3等。 一个名为“ Numpy”的python库提供了许多数组类型的数据结构,这是事实上的标准方法。 我们通过将值指定为np.array[]来声明要使用它们。

xs = np.array([-1.0,0.0,1.0,2.0,3.0,4.0],dtype = float)
ys = np.array([-3.0,-1.0,1.0,3.0,5.0,7.0],dtype = float)     

它们的关系是y = 2x-1

训练神经网络

训练神经网络的过程是在model.fit调用中“学习” xs和ys之间的关系。这就是我们上面讨论过的循环的地方,进行猜测,测量其好坏(也称为损失),使用优化器进行另一次猜测等。它将针对您所经历的时期数进行处理,指定。运行此代码时,您会在看到损失。

model.fit(xs,ys, epochs = 500)  #拟合

结果:
《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第1张图片
可以看到损失值很低了。
然后我们自己输入一个值,看看效果如何呀?

print(model.predict([10.0]))

结果:

[[18.999987]]

结果正确,约19。

课后小练习

问题描述:
尝试建立一个神经网络,根据一个简单的公式预测房屋价格。 因此,想象一下,如果房屋价格像房屋每间卧室50k + 50k一样容易,那么一间卧室的房子要100k,两间卧室的房子要150k,依此类推。 将如何创建一个学习此关系的神经网络,以便预测7卧室房屋的成本接近40万,等等。 提示:如果降低房价,网络可能会工作得更好。 您不必给出答案400 …最好创建可以预测数字4的内容,然后答案是“数十万”等。这里需要你们结合上面自写,写完后看看我的参考代码(。^▽^)。

import numpy as np
import tensorflow as tf
from tensorflow import keras

model = tf.keras.Sequential([ keras.layers.Dense(units=1,input_shape = [1])])
model.compile(optimizer="sgd",loss="mean_squared_error")

xs = np.array([1,2,3,4,5,6,7],dtype=float)
ys = np.array([100,150,200,250,300,350,400],dtype=float)

model.fit(xs,ys,epochs=500)

print(model.predict([8.0]))

结果:
《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第2张图片

三、 较复杂的神经网络

在上一个例子中,看到了如何创建一个神经网络,以解决要解决的问题。这给出了学习行为的明确示例。当然,在那种情况下,有点过分了,因为直接编写函数Y = 2x-1会更容易,而不是麻烦使用机器学习来学习一组固定的X和Y之间的关系。并将其扩展为所有值。 但是,编写这样的规则要困难得多的情况(例如计算机视觉问题)怎么办? 让我们看一个场景,在该场景中,我们可以识别出不同的衣服,这些衣服是从包含10种不同类型的数据集中训练出来的。
首先导入相关包

import tensorflow as tf

数据处理

Fashion MNIST数据可直接从tf.keras数据集API中获得。keras自带的数据集,如果网络问题下载不下来,可以下载我的数据(置顶资料下载),放入C:\用户\你的电脑名\.keras\datasets\

mnist = tf.keras.datasets.fashion_mnist    #下载并加载数据,如有数据将只加载

在此对象上调用load_data将为您提供两组两个列表,这两个列表将是包含服装项目及其标签的图形的训练和测试值。

(training_images,training_labels),(test_images,test_labels) = mnist.load_data()

这些值是什么样的? 让我们打印一个训练图像和一个训练标签以查看…具有数组中不同索引的实验。 例如,还要看一下索引42 …那是与索引0的引导不同的引导。

import matplotlib.pyplot as plt
plt.imshow(training_images[0])
plt.show()
print(training_labels[0])
print(training_images[0])

结果:
《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第3张图片

可以注意到,数字中的所有值都在0到255之间。如果我们在训练神经网络,出于各种原因,将所有值都视为0到1之间的过程会更容易,这一过程称为“规范化”。 幸运的是,在Python中,无需循环就可以很容易地标准化这样的列表。 可以这样操作:

training_images = training_images/255
test_images = test_images/255

模型构建

开始构建模型·

model = tf.keras.Sequential([tf.keras.layers.Flatten(),  #扁平化,
                            tf.keras.layers.Dense(128,activation=tf.nn.relu),
                            tf.keras.layers.Dense(10,activation = tf.nn.softmax)                                                        
                            ])

Sequential:定义了神经网络中各层的顺序 Flatten:还记得以前打印出的图像是正方形的地方吗?展平只是获取该正方形并将其变成一维集。 Dense:增加一层神经元,每层神经元都需要激活功能来告诉他们该做什么。有很多选择,但是现在就使用。 Relu实际上表示“如果X>0返回X,否则返回0”-------因此它所做的只是将值0或更大的值传递给网络的下一层。 Softmax采用一组值,并有效地选择最大的值,因此,例如,如果最后一层的输出看起来像[0.1、0.1、0.05、0.1、9.5、0.1、0.05、0.05、0.05],则可以节省您从钓鱼中寻找最大的价值,然后将其变成[0,0,0,0,1,0,0,0,0,0]目标是节省大量编码!

现在定义模型的下一步是实际构建模型。您可以像以前一样使用优化器和损失函数对其进行编译—然后通过调用model.fit对其进行训练,要求它将训练数据与训练标签相匹配-即让其确定训练数据之间的关系及其实际标签,因此在将来,如果您拥有看起来像训练数据的数据,那么它可以对这些数据的外观做出预测。

model.compile(optimizer="adam",   #optimizer = tf.train.AdamOptimizer(),2.0以下
             loss = "sparse_categorical_crossentropy",
             metrics=['accuracy'])
#开始拟合
model.fit(training_images,training_labels,epochs=10)

结果:
在这里插入图片描述
可以看到在训练集,它的准确率到达了91.12%,那么模型具体怎么样的,有没有过拟合呢?用测试集来看一下。

预测

model.evaluate(test_images,test_labels)

结果:
在这里插入图片描述
看似精度并不是很高,但想想,就10个周期,用了几秒钟训练出来的模型,还要啥自行车呀,已经是个很不错的结果了。

思考

  1. 请运行以下代码:它为每个测试图像创建一组分类,然后在分类中打印第一个条目。 运行后的输出是数字列表。这些数字代表什么?
classifications = model.predict(test_images)
print(classifications[0])
print(test_labels[0])

结果:

[1.07450695e-07 5.41081346e-10 6.13968343e-09 1.90720173e-09
 2.15319762e-09 1.99093833e-03 1.29562263e-08 4.95559396e-03
 1.05225340e-08 9.93053257e-01]
9

答:每个样本出现的概率,和概率最大的标签。

  1. 现在让我们看一下模型中的各层。 对512个神经元的密集层使用不同的值进行实验。 在损失,训练时间等方面得到什么不同的结果? 为什么认为是这种情况?
import tensorflow as tf
print(tf.__version__)

mnist = tf.keras.datasets.mnist

(training_images, training_labels) ,  (test_images, test_labels) = mnist.load_data()

training_images = training_images/255.0
test_images = test_images/255.0            #删除它loss:3630  未删除:loss 0.2949

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),   
                                    #512是3 4秒左右,损失。0.745
                                    #1024是6秒左右,损失0.0692
                                    #tf.keras.layers.Dense(1024, activation=tf.nn.relu),#多加一层  损失0.735,效果不么明显,时间更久 
                                    tf.keras.layers.Dense(512, activation=tf.nn.relu),   
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])

model.compile(optimizer = 'adam',
              loss = 'sparse_categorical_crossentropy')

model.fit(training_images, training_labels, epochs=5)

model.evaluate(test_images, test_labels)

classifications = model.predict(test_images)

print(classifications[0])
print(test_labels[0])

答:我是cpu跑的,512是3,4秒左右,损失。0.068;1024是6秒左右,损失0.0692。多加一层 损失0.735,效果不么明显,时间更久 ,我认为是此模型很简单,没必要一味加层数。
通过添加更多的神经元,我们必须进行更多的计算,从而减慢该过程的速度,但是在这种情况下,它们会产生很好的影响----我们的确会变得更加准确。 这并不意味着总是存在“越多越好”的情况,您可以很快达到收益递减的规律!

  1. 如果删除Flatten()层会发生什么。 为什么是这种情况?
    答:会得到有关数据形状的错误。 现在看来似乎很模糊,但它加强了经验法则,即网络中的第一层应与数据的形状相同。 现在,我们的数据是28x28的图像,而28层28个神经元将是不可行的,因此将“ 28,28”“展平”为784x1更有意义。 无需编写所有代码自行处理,而是在开始时添加Flatten()层,稍后将数组加载到模型中时,它们将自动展平。

  2. 考虑最后的(输出)层。为什么有10个呢? 如果的输出不等于10,会怎样?
    答:例如,尝试使用5训练网络 一旦发现意外值,将得到一个错误。 另一个经验法则----最后一层中的神经元数量应与您要分类的类的数量相匹配。在这种情况下,它是数字0-9,所以有10个数字,因此在最后一层中应该有10个神经元。

  3. 考虑网络中其他层的影响。如果在具有512的最后一层和具有10的最后一层之间添加另一层,将会发生什么。
    答:没有重大影响-----因为这是相对简单的数据。对于更复杂的数据,通常需要额外的图层。

  4. 考虑训练更多代或更少代的影响。 为什么会这样呢?
    答:尝试15代—可能会得到一个损失值比5更好的模型。尝试30代—可能会看到损失值停止下降,有时会增加。 这是所谓的“过度拟合”的副作用。如果没有改善自己的损失,浪费时间训练是没有意义的。

  5. 在训练之前,对数据进行了归一化,从0-255的值到0-1的值。 删除它会产生什么影响? 这是尝试的完整代码。为什么您认为得到不同的结果?
    答:归一化会使分类分布在一个均匀的范围内,如果没有归一化,数据准确率可能会下降。数据在标准数据中会工作的更好。

  6. 早些时候,当进行额外的训练时,会遇到损失可能会改变的问题。 需要花费一些时间来等待训练完成,并且可能认为“如果我在达到期望值时停止训练,那不是很好吗?” ----即95%的准确度可能对您来说足够了,如果您在3个代后达到了准确度,为什么还要坐在那里等待它完成更多代…那么将如何解决呢?
    代码如下:

import tensorflow as tf

class myCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if(logs.get('loss')<0.4):
      print("\nReached 60% accuracy so cancelling training!")
      self.model.stop_training = True

callbacks = myCallback()
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',metrics=["accuracy"])
model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])

课后小练习 —自写哈

在课程中,您学习了如何使用Fashion MNIST(包含服装项目的数据集)进行分类。还有另一个类似的数据集,称为MNIST,其中包含手写内容–数字0到9。
编写训练达到99%或更高准确度的MNIST分类器,并在没有固定数量的时期的情况下进行分类-即,一旦达到该准确度水平,就应该停止训练。
一些注意事项:

  • 它应该在少于10代内成功完成,因此可以将代数更改为10代,但没有更大的意义
  • 当达到或超过99%时,应打印出字符串“达到99%的准确度,因此取消训练!”
  • 如果添加任何其他变量,请确保使用与该类中使用的相同的名称

下面是参考代码。数据下载和上面一样,下载不下来的用我的。

#导入相关包
import tensorflow as tf

TensorFlow回调函数:tf.keras.callbacks.Callback

TensorFlow回调函数:tf.keras.callbacks.Callback

  • 定义在:tensorflow/python/keras/callbacks.py
  • 用于构建新回调的抽象基类。
    属性:
  • params:字典。训练参数(例如,详细程度,批量大小,epoch数…)。
  • model:keras.models.Model的实例。正在训练的模型的参考。
    被回调方法作为参数的logs字典将包含与当前批次或epoch相关的数量的键。
    目前,Sequential模型类的.fit()方法会在传入到回调函数的logs里面包含以下的数据:
  • on_epoch_end:包括acc和loss的日志,并且可选地包括val_loss (如果在fit中启用了验证),以及val_acc(如果启用了验证和准确性监视)。
  • on_batch_begin:logs包括size,当前批次中的样本数。
  • on_batch_end:日志包括loss,也可以选择acc (如果启用了准确性监控)。
    具体参考详情。
#设置训练结束条件
class myCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs = {}):
        if(float(logs.get("accuracy")) > 0.99):    #准确度超过0.99
            print("\n达到99%的准确度,因此取消训练!")
            self.model.stop_training = True   
callbacks = myCallback()

mnist = tf.keras.datasets.mnist
#读取数据
(training_images,training_labels),(test_images,test_labels) = mnist.load_data()
#归一化
training_images = training_images/255
test_images = test_images/255
#创建模型
model = tf.keras.Sequential([
                            tf.keras.layers.Flatten(input_shape = [28,28]),
                            #tf.keras.layers.Dense(1024,activation = tf.nn.relu),
                            tf.keras.layers.Dense(512,activation = tf.nn.relu),
                            tf.keras.layers.Dense(10,activation = tf.nn.softmax)
                            ])
#优化算法模型
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])   #adam优化,多类损失
#拟合
model.fit(training_images,training_labels,epochs=10,callbacks=[callbacks])
#测试集测试
model.evaluate(test_images,test_labels)

结果:
《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第4张图片
可以看到,到达了预定的精度,训练停止了。
测试集的损失和精度

10000/10000 [==============================] - 0s 34us/sample - loss: 0.0652 - accuracy: 0.9804

取得了不错的结果。

四、卷积神经网络—tensorflow2.0

使用卷积可以提高计算机视觉精度,在上面,我们了解了如何使用包含三层的深度神经网络(DNN)进行衣物数据的识别。输入层(以数据的形式),输出层(以所需的输出的形式)和隐藏层。尝试不同大小的隐藏层,训练时期数等对最终精度的影响。 为了方便起见,这里再次是整个代码。 运行它,并记下最后打印出的测试精度。

import tensorflow as tf 

#定义数据
mnist = tf.keras.datasets.fashion_mnist

#读出数据
(training_images,training_labels),(test_images,test_labels) = mnist.load_data()

#归一化
training_images = training_images/255
test_images = test_images/255

#创建模型
model = tf.keras.Sequential([tf.keras.layers.Flatten(),
                            tf.keras.layers.Dense(128,activation=tf.nn.relu),
                            tf.keras.layers.Dense(10,activation=tf.nn.softmax)
                            ])

#损失及优化
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])

#拟合
model.fit(training_images,training_labels,epochs=5)

结果:

Train on 60000 samples
Epoch 1/5
60000/60000 [==============================] - 3s 43us/sample - loss: 0.4980 - accuracy: 0.8260
Epoch 2/5
60000/60000 [==============================] - 2s 38us/sample - loss: 0.3736 - accuracy: 0.8657
Epoch 3/5
60000/60000 [==============================] - 2s 37us/sample - loss: 0.3352 - accuracy: 0.8781
Epoch 4/5
60000/60000 [==============================] - 2s 37us/sample - loss: 0.3136 - accuracy: 0.8851
Epoch 5/5
60000/60000 [==============================] - 2s 37us/sample - loss: 0.2937 - accuracy: 0.8930

#测试集测试
loss_test = model.evaluate(test_images,test_labels)
print("测试集损失:",loss_test[0],"\n精度:",loss_test[1])

结果:

10000/10000 [==============================] - 0s 32us/sample - loss: 0.3456 - accuracy: 0.8762
测试集损失: 0.34560067038536074 
精度: 0.8762

在训练中的准确性可能约为89%,在测试中的准确性为87%。还不错…但是如何使它变得更好呢?一种方法是使用称为卷积的东西。我在这里不打算详细介绍卷积,但最终的概念是它们缩小了图像的内容,以专注于特定的,独特的细节。 简而言之,将获得一个数组(通常为3x3或5x5)并将其传递到图像上。通过基于该矩阵内的公式更改基础像素,可以执行诸如边缘检测之类的操作。因此,如边缘检测定义的3x3,中间单元格为8,其所有邻居均为-1。在这种情况下,对于每个像素,您可以将其值乘以8,然后减去每个相邻像素的值。对每个像素执行此操作,将得到一个具有增强边缘的新图像。 这对于计算机视觉来说是完美的,因为通常可以像这样突出显示的功能将一项与另一项区分开,因此所需的信息量就少得多了……因为只是在突出显示的功能上进行训练。 那就是卷积神经网络的概念。在具有密集层之前,添加一些层进行卷积,然后进入密集层的信息将更加集中,甚至可能更准确。 运行以下代码----这与之前的神经网络相同,但是这次添加了卷积层。这将花费更长的时间,但要看一下对准确性的影响:(这是总体的代码,为了先看一下结果是否更好,对于代码的详细讲解后面会给出的)

import tensorflow as tf 

#定义数据
mnist = tf.keras.datasets.fashion_mnist
#读出数据
(training_images,training_labels),(test_images,test_labels) = mnist.load_data()
#归一化
training_images = training_images.reshape(60000,28,28,1)
training_images = training_images/255
test_images = test_images.reshape(10000,28,28,1)
test_images = test_images/255
#创建模型
model = tf.keras.Sequential([tf.keras.layers.Conv2D(64,(3,3),activation=tf.nn.relu,input_shape = (28,28,1)),  #卷积
                            tf.keras.layers.MaxPool2D(2,2),   #最大池化
                            tf.keras.layers.Conv2D(64,(3,3),activation=tf.nn.relu),  #卷积
                            tf.keras.layers.MaxPool2D(2,2) ,  #最大池化
                            
                            tf.keras.layers.Flatten(),
                            tf.keras.layers.Dense(128,activation=tf.nn.relu),
                            tf.keras.layers.Dense(10,activation=tf.nn.softmax)
                            ])

#损失及优化
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
#查看网络结构
model.summary()
#拟合
model.fit(training_images,training_labels,epochs=5)

结果:

	Model: "sequential_10"
	_________________________________________________________________
	Layer (type)                 Output Shape              Param #   
	=================================================================
	conv2d_12 (Conv2D)           (None, 26, 26, 64)        640       
	_________________________________________________________________
	max_pooling2d_12 (MaxPooling (None, 13, 13, 64)        0         
	_________________________________________________________________
	conv2d_13 (Conv2D)           (None, 11, 11, 64)        36928     
	_________________________________________________________________
	max_pooling2d_13 (MaxPooling (None, 5, 5, 64)          0         
	_________________________________________________________________
	flatten_10 (Flatten)         (None, 1600)              0         
	_________________________________________________________________
	dense_20 (Dense)             (None, 128)               204928    
	_________________________________________________________________
	dense_21 (Dense)             (None, 10)                1290      
	=================================================================
	Total params: 243,786
	Trainable params: 243,786
	Non-trainable params: 0
	_________________________________________________________________
	Train on 60000 samples
	Epoch 1/5
	60000/60000 [==============================] - 32s 540us/sample - loss: 0.4429 - accuracy: 0.8399
	Epoch 2/5
	60000/60000 [==============================] - 32s 542us/sample - loss: 0.2915 - accuracy: 0.8913
	Epoch 3/5
	60000/60000 [==============================] - 33s 546us/sample - loss: 0.2465 - accuracy: 0.9093
	Epoch 4/5
	60000/60000 [==============================] - 33s 546us/sample - loss: 0.2140 - accuracy: 0.9196
	Epoch 5/5
	60000/60000 [==============================] - 33s 547us/sample - loss: 0.1901 - accuracy: 0.9288
	
#测试集测试
loss_test = model.evaluate(test_images,test_labels)
print("测试集损失:",loss_test[0],"\n精度:",loss_test[1])

结果:

10000/10000 [==============================] - 1s 142us/sample - loss: 0.2714 - accuracy: 0.9009
测试集损失: 0.2714478527843952 
精度: 0.9009

训练数据和测试数据的准确度上升到约93%。 这很重要,而且朝着正确的方向迈出了一步! 尝试运行它以获取更多的代—大约20,然后探索结果!但是,尽管结果看起来确实不错,但由于称为“过度拟合”的问题,验证结果实际上可能会下降,这将在后面讨论。 (简而言之,当网络从训练集中很好地学习数据时,就会发生“过度拟合”,但是它过于专业化,无法仅对这些数据进行学习,因此在查看其他数据时效率较低。例如,如果一生都在学习 只看红色的鞋子,那么当看到红色的鞋子时,会很容易识别它,但是蓝色的绒面革鞋子可能会使您感到困惑) 然后,再次查看代码,逐步了解卷积的构建方式:

细讲代码

步骤1是收集数据。 注意这里有些变化,需要重新调整训练数据。 那是因为第一个卷积希望有一个包含所有内容的张量,所以列表中不是60000个28x28x1项,而是有一个60000x28x28x1的4D列表,并且对于测试图像也是如此。 如果不这样做,则在训练时会出现错误,因为卷积无法识别形状。

    import tensorflow as tf
    mnist = tf.keras.datasets.fashion_mnist
    (training_images, training_labels), (test_images, test_labels) = mnist.load_data()
    training_images=training_images.reshape(60000, 28, 28, 1)
    training_images=training_images / 255.0
    test_images = test_images.reshape(10000, 28, 28, 1)
    test_images=test_images/255.0

接下来是定义模型。现在,添加卷积,而不是顶部的输入层。参数为:

  1. 确定想要的卷积数(过滤器个数),纯粹是任意的,但最好从32左右开始
  2. 卷积的大小,在这种情况下为3x3网格
  3. 激活函数—在这种情况下,我们使用relu,相当于x> 0时返回x,否则返回0
  4. 第一层中,输入数据的形状。

将在卷积后面跟随一个MaxPooling层,该层然后被设计为压缩图像,同时保持卷积后突出显示的特征内容。通过为(MaxPooling)指定(2,2),效果是将图像大小缩小四分之一。此处无需赘述,其思想是创建一个2x2像素阵列,并选择最大的像素阵列,从而将4个像素变为1。它在整个图像中重复进行此操作,从而将水平数量减少了一半,并将垂直像素的数量减半,有效地将图像缩小了25%。
可以调用model.summary()来查看网络的大小和形状,并且您会注意到,在每个MaxPooling层之后,图像大小都会以这种方式减小。

  model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(2, 2), 	
#加入另一个卷积
 tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
 tf.keras.layers.MaxPooling2D(2,2),	
#现在将输出展平。之后,将拥有与非卷积相同的DNN结构
 tf.keras.layers.Flatten(),
#与卷积前示例相同,共有128个密集层和10个输出层:
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])

现在编译模型,调用fit方法进行训练,并从测试集中评估损失和准确性。

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)

卷积和池化层的可视化

该代码将以图形方式向我们展示卷积。 输出print(test_labels [; 100])向我们显示了测试集中的前100个标签,您可以看到索引0,索引23和索引28的标签都具有相同的值(9)。 他们都是鞋子。 让我们看一下在每个卷积上进行卷积的结果,将会看到它们之间的共同的特征。 现在,当DNN对该数据进行训练时,它的工作量大大减少了,并且可能基于这种卷积/池化组合在鞋子之间找到了共同点。

#查看前100个测试集标签
print(test_labels[:100])

结果“

[9 2 1 1 6 1 4 6 5 7 4 5 7 3 4 1 2 4 8 0 2 5 7 9 1 4 6 0 9 3 8 8 3 3 8 0 7
 5 7 9 6 1 3 7 6 7 2 1 2 2 4 4 5 8 2 2 8 4 8 0 7 7 8 5 1 1 2 3 9 8 7 0 2 6
 2 3 1 2 8 4 1 8 5 9 5 0 3 2 0 6 5 3 6 7 1 8 0 1 4 2]
import matplotlib.pyplot as plt
from tensorflow.keras import models 

f,axarr = plt.subplots(3,4)   #返回一个figure图像和一个子图ax的array列表
FIRST_IMAGE = 0
SECOND_IMAGE = 23
THIRD_IMAGE = 28
CONVOLUTION_NUMBER = 2

layer_outputs = [layer.output for layer in model.layers]

activation_model = tf.keras.models.Model(inputs = model.input,outputs = layer_outputs)

for x in range(0,4):
    f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
    axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
    axarr[0,x].grid(False)
    f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]
    axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
    axarr[1,x].grid(False)
    f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]
    axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
    axarr[2,x].grid(False)

《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第5张图片

思考

  1. 尝试编辑卷积。 将32s更改为16或64。这将对准确性和/或训练时间产生什么影响。
  2. 删除最后的卷积。 这将对准确性或培训时间产生什么影响?
  3. 如何添加更多卷积? 您认为这会产生什么影响? 尝试一下。
  4. 上面,实现了一个回调以检查损失功能并在达到一定量后取消训练。 在这里实现一下。
    编写代码,来看看,细细品一下吧!
    你品,你品,你细细品
import tensorflow as tf 
#定义数据
mnist = tf.keras.datasets.fashion_mnist
#读出数据
(training_images,training_labels),(test_images,test_labels) = mnist.load_data()
#归一化
training_images = training_images.reshape(60000,28,28,1)
training_images = training_images/255
test_images = test_images.reshape(10000,28,28,1)
test_images = test_images/255
#创建模型
#过滤器个数64 acc = 092.  0.90 时间:32s 
#过滤器个数32 acc = 092.  0.90 时间:18s 
#过滤器个数16 acc = 092.  0.90 时间:17s 
#对于此数据集,过滤器大小不会明显影响准确率,但对时间影响很大
model = tf.keras.Sequential([tf.keras.layers.Conv2D(64,(3,3),activation=tf.nn.relu,input_shape = (28,28,1)),  #卷积 acc(64) = 092(32s) 
                            tf.keras.layers.MaxPool2D(2,2),   #最大池化
                            
                            tf.keras.layers.Conv2D(64,(3,3),activation=tf.nn.relu),  #卷积
                            tf.keras.layers.MaxPool2D(2,2) ,  #最大池化
                                                          
                            #tf.keras.layers.Conv2D(64,(3,3),activation=tf.nn.relu),  #卷积
                            #tf.keras.layers.MaxPool2D(2,2) ,  #最大池化                           
                             
                            tf.keras.layers.Flatten(),
                            tf.keras.layers.Dense(128,activation=tf.nn.relu),
                            tf.keras.layers.Dense(10,activation=tf.nn.softmax)
                            ])
#损失及优化
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
model.summary()
#拟合
model.fit(training_images,training_labels,epochs=5)

#测试集测试
loss_test = model.evaluate(test_images,test_labels)
print("测试集损失:",loss_test[0],"\n精度:",loss_test[1])

上面的题做好了,来对对我的参考答案( ̄︶ ̄*))

  1. 尝试编辑卷积。 将32s更改为16或64。这将对准确性和/或训练时间产生什么影响。
    过滤器个数64 acc = 092. 0.90 时间:32s
    过滤器个数32 acc = 092. 0.90 时间:18s
    过滤器个数16 acc = 092. 0.90 时间:17s
    对于此数据集,过滤器大小不会明显影响准确率,但对时间影响很大

  2. 删除最后的卷积。 这将对准确性或培训时间产生什么影响?
    删除一层卷积: 过滤器个数64 acc = 0946. 0.914 时间:24s
    未删除一层卷积:过滤器个数64 acc = 092. 0.90 时间:32s
    对于此数据集,删除一层卷积时间更少,准确率更高

  3. 如何添加更多卷积? 您认为这会产生什么影响? 尝试一下。
    未添加一层卷积:过滤器个数64 acc = 092. 0.90 时间:32s
    多加一层卷积: 过滤器个数64 acc = 087. 0.87 时间:30s
    卷积层增多了,准确率反而减少了,原因是可能造成了过拟合。

  4. 上面,实现了一个回调以检查损失功能并在达到一定量后取消训练。 在这里实现一下。

import tensorflow as tf 


#回调函数
class myCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs = {}):
        if(logs.get("accuracy") > 0.90):
            print("\n准确率到达了90%,停止迭代!")
            self.model.stop_training = True

#实例化
callbacks = myCallback()
#定义数据
mnist = tf.keras.datasets.fashion_mnist
#读出数据
(training_images,training_labels),(test_images,test_labels) = mnist.load_data()
#归一化
training_images = training_images.reshape(60000,28,28,1)
training_images = training_images/255
test_images = test_images.reshape(10000,28,28,1)
test_images = test_images/255
model = tf.keras.Sequential([tf.keras.layers.Conv2D(16,(3,3),activation=tf.nn.relu,input_shape = (28,28,1)),  #卷积 acc(64) = 092(32s) 
                            tf.keras.layers.MaxPool2D(2,2),   #最大池化
                    
                            tf.keras.layers.Flatten(),
                            tf.keras.layers.Dense(128,activation=tf.nn.relu),
                            tf.keras.layers.Dense(10,activation=tf.nn.softmax)
                            ])
#损失及优化
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
model.summary()
#拟合
model.fit(training_images,training_labels,epochs=5,callbacks=[callbacks])

#测试集测试
loss_test = model.evaluate(test_images,test_labels)
print("测试集损失:",loss_test[0],"\n精度:",loss_test[1])

结果:
《TensorFlow2.0》一、机器学习和深度学习简介及基础编程 part 1_第6张图片完成到达条件取消训练,回调函数。

五、结语

好了,第一部分先到这里吧!下节我们将通过在2D灰度图像上创建基本卷积来探索卷积如何工作,再给出一个CNN的课后题练习一下。然后细讲一个CNN二分类的例子。下章见!

你可能感兴趣的:(TensorFlow,2.0,深度学习,tensorflow,神经网络)