前言
之前有写过几篇TensorFlow
相关文章,但是用的比较底层的写法,比如tf.nn
和tf.layers
,也写了部分基本模型如自编码和对抗网络等,感觉写起来不太舒服,最近看官方文档发现它的教程基本都使用的keras API
,这就尴尬了,学一波
国际惯例,参考博客:
官方开始案例
keras比tensorflow差在哪里?
其实网上有很多博客了,但是为实验了一下跑不起来,而且按照官方文档理解的使用算法和网络上的博客又不同,比如这位大佬的博客中有这样一行代码:
model.add(Dense(input_dim=1, output_dim=1, init='uniform', activation='linear'))
但是我去找官方文档tf.keras.Dense
发现并没input_dim,output_dim
这两个参数,很多博客都有这样写,难道是keras
而非是以keras
为前端的Tensorflow
的参数?感觉看着迷迷糊糊,还不如自己按照官方文档手撸一波。
学习步骤还是之前的思路:线性回归,全连接的手写数字分类,卷积,RNN,RBM
【注】如果本地电脑没有TensorFlow环境,可以试用官方提供的在线编辑调试网站colab,灰常方便,而且还能启动GPU和TPU,这也太良心了吧,在colab的修改->笔记本设置->硬件加速
可以启用
线性回归
直接用 $ y=3x+5$ 这个函数
-
引入相关包
import tensorflow as tf import numpy as np from tensorflow import keras
-
建立数据集
trX=np.linspace(-1,1,101) trY=3*trX+5
-
创建模型:只具有一个单隐层,三种写法,其实我更喜欢第三种写法
#写法一 #model=tf.keras.models.Sequential([ # keras.layers.Flatten(), # keras.layers.Dense(1) ]) #写法二 # model= keras.Sequential() # model.add(keras.layers.Flatten()) # model.add(keras.layers.Dense(units=1,use_bias=True)) #写法三 inputs = tf.keras.Input(shape=[1,]) x= tf.keras.layers.Dense(1)(inputs) model = tf.keras.models.Model(inputs=inputs,outputs=x)
这里注意的就是层的使用方法了,首先要用
Sequential
建立一个序列容器,然后再将模型逐层add
进来,Flatten
是展平向量,Dense
是全连接。或者第三种方法tf.keras.models.Model
将输入输出嵌入模型中。
【注意】
写法一和二是无法直接打印网络结构的,因为没指定网络输入大小,或者没开始训练,强行打印的方法就是,在Sequential
的第一层加入input_shape=[x,x]
这样的参数,比如model=tf.keras.models.Sequential([keras.layers.Dense(1,input_shape=[1,]) ])
这样上述三种方法都可以用model.summary()
打印网络结构了。
-
编译优化算法:
model.compile(optimizer=tf.train.RMSPropOptimizer(learning_rate=0.01),loss='mse',metrics=['mae'])
这里需要注意的是三个参数
optimizer
,不建议直接写adam
,sgd
之类的,最好是用tf
自带的优化器,loss表示损失,这个不太清楚MSE在tf
中怎么点出来,只好用mse
的形式写了,评估函数是mae
,这个回头看看怎么去掉引号 -
训练:
model.fit(trX,trY,epochs=1000)
-
查看权重
以上基本是完成了参数学习过程,有时候我们希望看看参数,这里可以先输出每层的名称看看都存了啥print(model.layers) ''' [<tensorflow.python.keras.layers.core.Flatten object at 0x0000027AED6A3978>, <tensorflow.python.keras.layers.core.Dense object at 0x0000027AED6A3D68>] '''
我们需要的权重在第二个layers里面,因为从0开始编号,所以取权重的方法是
model.layers[1].get_weights() ''' [array([[2.987659]], dtype=float32), array([5.0043736], dtype=float32)] '''
很容易发现不仅把权重输出了,偏置项也在
-
评估模型
我们也可以制作训练集查看误差model.evaluate(trX,trY) ''' 101/101 [==============================] - 0s 594us/step [4.496799705845147e-07, 0.000640394664046788] '''
感觉第一个应该是损失,第二个是误差
-
预测数值
输入10,那么y=3*10+5=35model.predict([10]) ''' array([[34.997227]], dtype=float32) '''
基本的使用都在这里了,相对于使用更底层的TensorFlow
代码,貌似用keras
更加方面了,尤其是建立模型和预测结果上
分类
-
导入相关包
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(512,activation=tf.nn.relu),tf.keras.layers.Dropout(0.2),tf.keras.layers.Dense(10,activation=tf.nn.softmax) ])
-
编译优化算法
#编译模型 model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
-
训练和评估
model.fit(x_train,y_train,epochs=5) model.evaluate(x_test, y_test) ''' Epoch 1/5 60000/60000 [==============================] - 15s 250us/step - loss: 0.2026 - acc: 0.9406 Epoch 2/5 60000/60000 [==============================] - 13s 213us/step - loss: 0.0809 - acc: 0.9751 Epoch 3/5 60000/60000 [==============================] - 13s 209us/step - loss: 0.0524 - acc: 0.9832 Epoch 4/5 60000/60000 [==============================] - 12s 206us/step - loss: 0.0374 - acc: 0.9880 Epoch 5/5 60000/60000 [==============================] - 12s 202us/step - loss: 0.0280 - acc: 0.9913 10000/10000 [==============================] - 1s 70us/step [0.0750152821913769, 0.9798] '''
后记
感觉前面还是不够简化,因为学到这里,我们在编译模型时,只会使用引号定义优化方法,作为一名码农,还是喜欢点点点地点出来
看官网的介绍:
compile(optimizer,loss=None,metrics=None,loss_weights=None,sample_weight_mode=None,weighted_metrics=None,target_tensors=None,distribute=None,**kwargs
)
部分参数描述:
optimizer
:优化器的字符串名字,或者优化器实例,具体看optimizers
loss
:目标函数的名字或者目标函数,看loss
metrics
:训练或测试模型所使用的评估方法,一般使用metrics=['accuracy']
当我们点击优化器和loss的时候,很容易发现,这两个东东都隶属于tf.keras
的类,尝试点一下
除了最后一个常用accuracy
,不清楚还能用什么以外,差不多已经达到了解放双手的效果,我们只需要尝试点点点就能依据智能提示构建一个非常简单的keras模型,其实后来想了想有时候我们的目标函数和评估函数是一样的,那么能否直接使用tf.keras.losses里面的损失函数作为评估函数呢,然后试了一下,稳如狗,可以,但是要注意是列表形式放进去;
比如上面分类例子中使用的:
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
可以换成
#初始化一个优化方法实例
optim=tf.keras.optimizers.Adam();
#编译模型
#编译模型
model.compile(optimizer= optim,loss=tf.keras.losses.sparse_categorical_crossentropy,metrics=[tf.keras.losses.MSE])
后记
接下来就要看看如何使用自己的数据去训练keras构建的模型,从第一个回归的例子来看,好像没有之前学tensorflow一样那么麻烦,需要使用比较复杂的数据流。
下节预告,构建手写数字分类系统,使用卷积的方法,并且要能保存和调用模型
本章代码戳这里 ,记得使用colab打开,可以直接运行,美滋滋