这是我大概一年多以前跟着慕课上的网易有道的课程学下来的笔记,其中部分图片出自于课程截图,如造成侵权请联系我,我会删除。
这个其实一直躺在我的草稿里,其中的踩坑部分我也之前发过博客说明了,今天突然想起来这个,也只是希望我做的这一点笔记能够对有需要的人起到一点点的帮助,当然如果其中有我记录出现错误的地方,也欢迎各位大佬的批评指正:D。
其实这个课程我也没完全听完,如果有感兴趣的同学可以在 中国大学mooc 搜索一下TensorFlow入门实操课程,里面有更详细和全面的讲解。
人类根据经验能够对各种各样的事物进行预判,比如买西瓜的时候通过色泽、瓜蒂、敲声等特征来判断。那计算机能帮忙吗?
机器学习就是研究如何通过计算的手段利用经验来改善系统自身的性能。
好处:速度是相对比较快的:D让人学习大概几天或者时间更长,但是让机器学习就是几分钟或者几个小时就能学得非常好。前提是我们要有足够的数据。
示例:Activity Recognition(活动识别)
最后一个有时候是停止的有时候是和走路一样的速度,但是它是在打高尔夫。用传统方式大概你要查很多资料或者看看别人怎么做。
用机器学习方式就可以让她带着传感器然后把她的行动数据记录下来,打上标签,把数据和标签都输入机器,让机器自己生成规则。也叫做有监督学习,即:标签是我们事先知道的。
anaconda
from tensorflow import keras
import numpy as np
#构建模型
model = keras.Sequential([keras.layers.Dense(units=1,input_shape=[1])])
model.compile(optimizer='sgd',loss='mean_squared_error')
#准备训练数据
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)
#训练模型
model.fit(xs,ys,epochs=500)
#使用模型
print(model.predict([10.0]))
第一行:
keras
是tensorflow
的一个高级API,使用的时候比较简单layers
代表是一层神经元,units
代表这一层里只有一个,input_shape
指输入值,因为我们的输入只有一个x
,所以在这里输入是1第二行:
loss fuction
,就是根据什么来检测它的损失函数,optimizer
说明它要根据什么来优化mean_squared_error
就是指看测量得到的值和理论值之间的差,即下图中的线段长度,这个值平方一下就是一个正方形,把从1-n的所有差值的平方加起来再除以n得到MSE,偏差越小,MSE也就越小PS:对于线性问题经常用这种方法来检测它的损失
检测数据部分:
Numpy
把它转成array
,可以制定数据类型训练模型部分:
fit
方法,告诉它对应的x
和y
,epochs
指训练的次数使用模型部分:
用JupyterLab
写的,运行结果如下
注!!!
一开始未声明keras
和np
从哪来的
loss
打错了
以上两条为我第一次敲代码时犯的白痴错误
最好打一行就检查一下有无敲错的地方,一大堆的时候不好找
模型训练过程中,loss
越来越小证明训练对了
(ps:其实也不一定越来越小,训练过程中可能会产生一定的波动,但是只要总体的趋势是下降的就说明你的训练没有问题。)
如何让机器来识别物品呢?
Fashion MNIST
是一个有10个类别的服装数据集
设想:用数据和标签做训练,最后得到一个神经网络模型
Fashion MNIST
数据集#加载fashion MNIST数据集
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels)=fashion_mnist.load_data()
print(train_images.shape)#看大小
keras
的数据集里有fashion MNIST
,通过load_data
方法可以把数据加载进来
加载的时候分为四个变量:train_images
是用来的数据,train_labels
是每张图片对应的标签是什么,test_images
是测试用的图片,test_labels
是测试用的标签
运行截图:
这里显示有6万张,每张是28*28
可以这样看具体的值,每一个都是灰度值
#看每张图片什么样子
import matplotlib.pyplot as plt
plt.imshow(train_images[0])
小插曲:JupyterLab
报错No module named 'matplotlib'
解决:命令行激活tensorflow
环境
activate tensorbase #tensorbase是我的虚拟环境的名称
安装matplotlib
pip install matplotlib
再测试就可以查看图像了
之所以分为train
和test
是为了后面要验证模型的准确度
在上述加载数据集的基础上
#构造神经元模型
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28,28)),
keras.layers.Dense(128,activation=tf.nn.relu),
keras.layers.Dense(10,activation=tf.nn.softmax)
])
#查看模型样子
model.summary()
input_shape
指定输入大小。keras.layers.Dense(10,activation=tf.nn.softmax)
的10指10个神经元,因为是概率值,激活函数用softmax
。示意图:
神经元做什么:把每个输入和它相应的权重相乘然后加起来得到c,然后把c放到激活函数里面。函数的输出就是整个神经元最后的输出。
激活函数:
Relu
激活函数:是用在中间层的,特点:只有当输入是正数的时候才会有输出
Softmax
激活函数:特点:把输出压缩在0-1之间
运行截图:
看到Parameters
,即最后一列,可以通过这个来判断网络的结构,10480其实是784个像素x128个神经元,每一个像素都作为输入给一个神经元。
? 但是784x128其实是100352,实际却是100480这是为什么?
答:其实每一层都有一个bias
,这个是自动加的,但是输出层是没有的。相当于线性方程时的截距。
1290来源:输出层是10个神经元,输入给它的是128+1个bias
。
这种网络结构又叫做全连接的网络结构
在上述构造神经元网络模型的基础上
#评估和训练模型
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['accuracy'])
model.fit(train_images,train_labels,epochs=5)
model.evaluate(test_images,test_labels)
第一步指定优化的方法。
也可以将第一步中的优化写为optimizer=tf.optimizers.Adam()
,Adam
是训练时经常使用的优化的方法;
损失函数可写为loss=tf.losses.sparse_categorical_crossentropy
,输出的数据结果是类别的时候就会用categorical
,是否带sparse
的区别是现在的标签是整数所以带sparse
,如果label
是one_hot
,即里面只有一个是1的时候可以不带;
metrics
表示训练时想看到它的精度
第二步用训练数据去训练,epochs
表示让数据跑几次
最后用evaluate
去评估模型的效果
为了让训练的效果更好,要给数据做normalization
或scaling
,(归一化)即让它变为0-1之间的数。
train_images_scaled=train_images/255 #为了训练得更好
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['accuracy'])
model.fit(train_images_scaled,train_labels,epochs=5)
test_images_scaled=test_images/255 #训练的时候除以255评估时也要除
model.evaluate(test_images_scaled,test_labels)
如何用这个模型来判断单张图片的类别?
可以用模型的predict
方法
model.predict([[test_images[0]/255]])
踩坑:上述代码使用的时候会报错,要改成如下的
model.predict((test_images[0]/255).reshape(1,28,28,1))
#更直观一点
import numpy as np
np.argmax(model.predict((test_images[0]/255).reshape(1,28,28,1)))
运行结果是:9
和它的标签一样
训练次数不是越多越好,训练次数过多会出现过拟合的情况:在训练集上效果很好,泛化能力很差。
如何观察到过拟合:训练的loss
和测试的loss
出现分叉的时候就出现了过拟合。
需要根据一些条件来终止训练,可以利用tensorflow
中的callbacks
来终止训练
import tensorflow as tf
from tensorflow import keras
class myCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self,epoch,logs={}):
if(logs.get('loss')<0.4):
print("\nloss is low 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_scaled=training_images/255.0
test_images_scaled=test_images/255.0
model = tf.keras.Sequential([
keras.layers.Flatten(),
keras.layers.Dense(512,activation=tf.nn.relu),
keras.layers.Dense(10,activation=tf.nn.softmax)
])
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['accuracy'])
model.fit(train_images_scaled,train_labels,epochs=5,callbacks=[callbacks])
数据集中的图片物品都在正中位置,实际中捕捉到的图片,物品往往会在偏于一侧的位置,或者会有些旋转。
CNN的思想:学习一个物品的特征来判断物品。
卷积操作:过滤器中的数值和像素对应位置相乘,然后再加起来。
过滤器在图片上移动,一格一格地移动,每移动一次就进行一次卷积操作。
一直移动到最后一行,输出是4x4的
不同的过滤器会有不同的效果:留下竖直线/水平线
卷积神经网络的训练其实就是在过滤器里面的数据
每次卷积操作执行后还要经过一个Max Pooling
:用于增强图像特征,减少数据
计算过程:如在卷积后的4x4的区域上以2x2的区域扫描,在2x2的区域里取最大的数值,将最大的数值留下,最后变成一个2x2的矩阵。
卷积神经网络是在上述全连接网络基础上,增加四层
#加载fashion MNIST数据集
import tensorflow as tf
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels)=fashion_mnist.load_data()
#构造神经元模型
model = keras.Sequential()
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28,1)))
model.add(keras.layers.MaxPooling2D(2,2))
model.add(keras.layers.Conv2D(64,(3,3),activation='relu'))
model.add(keras.layers.MaxPooling2D(2,2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128,activation=tf.nn.relu))
model.add(keras.layers.Dense(10,activation=tf.nn.softmax))
train_images_scaled=train_images/255 #为了训练得更好
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['accuracy'])
model.fit(train_images_scaled.reshape(-1,28,28,1),train_labels,epochs=5)
relu
,规定输入是(28,28,1)因为只有灰度值。可见效果比上面的全连接神经网络好
通过model.summary
可见网络结构
shape
:
第一层:输入是28x28,过滤器是3x3,会去掉两个像素所以最后变成26x26的尺寸,64指64个过滤器。
maxPooling
把尺寸缩小为原来的1/4,长宽各减半。第三、死层重复一、二层操作。
flatten
把所有的展平,一共是5x5x64=1600个神经元
parameters
:
第一层:(3x3+1)x64=640,因为过滤器是3x3,再加一个bias
maxPooling
没有调整参数,所以是0
第三层:(3x3x64+1)x64=36928
#看看每一层发生了什么
import matplotlib.pyplot as plt
layer_outputs = [layer.output for layer in model.layers]#读取Model的每个层
activation_model = tf.keras.models.Model(inputs = model.input,outputs = layer_outputs)#input和输出层放在一起构成一个对象
pred = activation_model.predict(test_images[0].reshape(1,28,28,1))#把这个对象用到一张图片上测试
pred
项目过程:准备训练数据、构建模型、训练模型、优化参数
#获得训练数据,这是validation set验证集
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip \
-O D:/学习资料/机器学习/validation-horse-or-human.zip
windows上需要安装一下wget
wget下载地址:https://eternallybored.org/misc/wget/
将下载下来的.exe
文件放在C盘Windows/System32
文件夹下
在命令行输入 wget --version
#用来训练的train set
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip \
-O D:/学习资料/机器学习/horse-or-human.zip
为什么把马和人分开:为了更容易打标签,比把所有文件放在一起通过文件名区分标签类型更容易
把下载好的网络图片变为可用于神经元网络训练的数据
用到的组件image data generator
,从keras
里面引用
真实数据的特点:
from tensorflow.keras.preprocessing.image import ImageDataGenerator
#创建两个数据生成器,指定scaling范围0-1
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)
#指向训练数据文件夹
train_generator = train_datagen.flow_from_directory(
'D:/学习资料/机器学习/horse-or-human/',#训练数据所在文件夹
target_size=(300,300),#指定输出尺寸
batch_size=32,
class_mode='binary'#指定二分类
)
#指向测试文件夹
validation_generator = validation_datagen.flow_from_directory(
'D:/学习资料/机器学习/validation-horse-or-human/',
target_size=(300,300),
batch_size=32,
class_mode='binary'
)
手动处理也可以,但是比较麻烦
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.optimizers import RMSprop
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16,(3,3),activation='relu',input_shape=(300,300,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(32,(3,3),activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64,(3,3),activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512,activation='relu'),
tf.keras.layers.Dense(1,activation='sigmoid')
])
model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])
history = model.fit(
train_generator,
epochs=15,
verbose=1,
validation_data = validation_generator,
validation_steps = 8
)
#查看模型结构 model.summary()
Conv2D
这样三层,后边是一个全连接层,最后是一个神经元,输出要么是0,要么是1,二分类,所以激活函数是sigmoid
,如果是多分类的话用Softmax
RMS
,也可以换成其他的试试怎样调整层数、参数等等
手工调整,看最后的训练精度
写个循环来调整数值,记录最后的训练精度
可利用KerasTuner的库来做参数的优化
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.optimizers import RMSprop
from kerastuner.tuners import Hyperband
from kerastuner.engine.hyperparameters import Hyperparameters
hp = HyperParameters()
#将创建模型的代码作为函数
def build_model(hp):
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(hp.Choice('num_filters_layer0',values=[16,64],default=16),(3,3),activation='relu',input_shape=(300,300,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(32,(3,3),activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64,(3,3),activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512,activation='relu'),
tf.keras.layers.Dense(1,activation='sigmoid')
])
model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])
return model
tuner = Hyperband(
build_model,#用哪个函数来生成模型
objective='val_acc',#用测试集的acc为目标
max_epochs=15,#估计大概几次可以达到会聚
directory='horse_human_params'#给存入本地的数据指定一个目录和名称
hyperparameters=hp,#使用这个变量
project_name='my_horse_human_project'#存储时随便取的名字
)
原理:把需要探索的值用high parameter
代替
hp.Choice('num_filters_layer0')
随便取个名字,训练好之后会把数值和这个名字对应起来保存下来,values
指定一个范围hp.Int("hidden_units",128,512,step=32)
表示有几个神经元,同样给它取个名字,给它一个范围,32、32地增加import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.optimizers import RMSprop
from kerastuner.tuners import Hyperband
from kerastuner.engine.hyperparameters import HyperParameters
hp = HyperParameters()
#将创建模型的代码作为函数
def build_model(hp):
model = tf.keras.models.Sequential([])
model.add(tf.keras.layers.Conv2D(hp.Choice('num_filters_layer0',values=[16,64],default=16),(3,3),activation='relu',input_shape=(300,300,3)))
model.add(tf.keras.layers.MaxPooling2D(2,2))
#应该有几层,数据不能太大,因为max Pooling会越来越小,输出尺寸会越来越小
for i in range(hp.Int("num_conv_layers",1,3)):
model.add(tf.keras.layers.Conv2D(hp.Choice(f'num_filters_layer{i}',values=[16,64],default=16),(3,3),activation='relu')),
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(hp.Int("hidden_units",128,512,step=32),activation='relu'))
model.add(tf.keras.layers.Dense(1,activation='sigmoid'))
model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])
return model
tuner = Hyperband(
build_model,#用哪个函数来生成模型
objective='val_acc',#用测试集的acc为目标
max_epochs=15,#估计大概几次可以达到会聚
directory='horse_human_params',#给存入本地的数据指定一个目录和名称
hyperparameters=hp,#使用这个变量
project_name='my_horse_human_project'#存储时随便取的名字
)
#搜参数
tuner.search(train_generator,epochs=10,validation_data = validation_generator)
踩坑之处:
一直报错No module named ‘kerastuner‘
,是因为没安装
解决:
命令行终端切换到虚拟环境中
activate tensorbase
安装命令
pip install -U keras-tuner
报错:module ‘tensorflow._api.v2.distribute’ has no attribute ‘tpustrategy’
啊这个报错困扰了我一天,百度了一圈发现问题可能是之前下载的tensoflow
版本是2.2.0要升级到最新的版本才可以。
于是我兴冲冲地用命令行去更新,安装完成之后,本地的确实更新到2.4.1版本了,但是虚拟环境里完全没有!!
踩坑了一圈,我终于,找到了解决方法
打开Anaconda Prompt
!!!!
win10如何查看安装的tensorflow
是CPU还是GPU版本
首先输入pyhton
再输入以下代码
import tensorflow as tf
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
print (sess.run(c))
运行结果就会显示是CPU还是GPU
如果之前是CPU版本的用
pip install --upgrade --ignore-installed tensorflow
GPU版本的用
pip install --upgrade --ignore-installed tensorflow-gpu
安装成功运行后会自动卸载前一个版本留下最新的版本
如何查看tensorflow
版本号
还是在Anaconda Prompt
里打开python
环境,即输入python
再输入
import tensorflow as tf
tf.__version__#查看版本号
更新完最好再查看一下版本,免得自以为更新好了
更新到最新版本后我的就可以运行了,简直泪目,乌乌:D然后它运行了好久
读取参数
best_hps=tuner.get_best_hyperparameters(1)[0]
print(best_hps.values)
#用参数构建模型
model=tuner.hypermodel.build(best_hps)
model.summary()