3-3,高阶API示范

    TensorFlow的高阶API主要为tf.keras.models提供的模型的类接口。

    使用Keras接口有以下3种方式构建模型:使用Sequential按层顺序构建模型,使用函数式API构建任意结构模型,继承Model基类构建自定义模型。

    此处分别演示使用Sequential按层顺序构建模型以及继承Model基类构建自定义模型。

    此范例我们使用Sequential按层顺序构建模型,并使用内置model.fit方法训练模型【面向新手】。

    1,准备数据

    1. import pandas as pd
    2. from matplotlib import pyplot as plt
    3. import tensorflow as tf
    4. from tensorflow.keras import models,layers,losses,metrics,optimizers
    5. #样本数量
    6. n = 400
    7. # 生成测试用数据集
    8. X = tf.random.uniform([n,2],minval=-10,maxval=10)
    9. w0 = tf.constant([[2.0],[-3.0]])
    10. b0 = tf.constant([[3.0]])
    11. Y = X@w0 + b0 + tf.random.normal([n,1],mean = 0.0,stddev= 2.0) # @表示矩阵乘法,增加正态扰动
    1. # 数据可视化
    2. %matplotlib inline
    3. %config InlineBackend.figure_format = 'svg'
    4. plt.figure(figsize = (12,5))
    5. ax1 = plt.subplot(121)
    6. ax1.scatter(X[:,0],Y[:,0], c = "b")
    7. plt.xlabel("x1")
    8. plt.ylabel("y",rotation = 0)
    9. ax2 = plt.subplot(122)
    10. ax2.scatter(X[:,1],Y[:,0], c = "g")
    11. plt.xlabel("x2")
    12. plt.ylabel("y",rotation = 0)
    13. plt.show()

    2,定义模型

    1. tf.keras.backend.clear_session()
    2. model = models.Sequential()
    3. model.add(layers.Dense(1,input_shape =(2,)))
    4. model.summary()
    1. Model: "sequential"
    2. _________________________________________________________________
    3. Layer (type) Output Shape Param #
    4. =================================================================
    5. dense (Dense) (None, 1) 3
    6. =================================================================
    7. Total params: 3
    8. Trainable params: 3
    9. Non-trainable params: 0

    3,训练模型

    1. Epoch 197/200
    2. 400/400 [==============================] - 0s 190us/sample - loss: 4.3977 - mae: 1.7129
    3. Epoch 198/200
    4. 400/400 [==============================] - 0s 172us/sample - loss: 4.3918 - mae: 1.7117
    5. Epoch 199/200
    6. 400/400 [==============================] - 0s 134us/sample - loss: 4.3861 - mae: 1.7106
    7. Epoch 200/200
    8. 400/400 [==============================] - 0s 166us/sample - loss: 4.3786 - mae: 1.7092
    9. w = [[1.99339032]
    10. [-3.00866461]]
    11. b = [2.67018795]
    1. # 结果可视化
    2. %matplotlib inline
    3. %config InlineBackend.figure_format = 'svg'
    4. w,b = model.variables
    5. plt.figure(figsize = (12,5))
    6. ax1 = plt.subplot(121)
    7. ax1.scatter(X[:,0],Y[:,0], c = "b",label = "samples")
    8. ax1.plot(X[:,0],w[0]*X[:,0]+b[0],"-r",linewidth = 5.0,label = "model")
    9. ax1.legend()
    10. plt.xlabel("x1")
    11. plt.ylabel("y",rotation = 0)
    12. ax2.scatter(X[:,1],Y[:,0], c = "g",label = "samples")
    13. ax2.legend()
    14. plt.xlabel("x2")
    15. plt.ylabel("y",rotation = 0)
    16. plt.show()

    二,DNN二分类模型

    此范例我们使用继承Model基类构建自定义模型,并构建自定义训练循环【面向专家】

    1,准备数据

    1. import numpy as np
    2. import pandas as pd
    3. from matplotlib import pyplot as plt
    4. import tensorflow as tf
    5. from tensorflow.keras import layers,losses,metrics,optimizers
    6. %matplotlib inline
    7. %config InlineBackend.figure_format = 'svg'
    8. #正负样本数量
    9. n_positive,n_negative = 2000,2000
    10. #生成正样本, 小圆环分布
    11. r_p = 5.0 + tf.random.truncated_normal([n_positive,1],0.0,1.0)
    12. theta_p = tf.random.uniform([n_positive,1],0.0,2*np.pi)
    13. Xp = tf.concat([r_p*tf.cos(theta_p),r_p*tf.sin(theta_p)],axis = 1)
    14. Yp = tf.ones_like(r_p)
    15. #生成负样本, 大圆环分布
    16. r_n = 8.0 + tf.random.truncated_normal([n_negative,1],0.0,1.0)
    17. theta_n = tf.random.uniform([n_negative,1],0.0,2*np.pi)
    18. Xn = tf.concat([r_n*tf.cos(theta_n),r_n*tf.sin(theta_n)],axis = 1)
    19. Yn = tf.zeros_like(r_n)
    20. #汇总样本
    21. X = tf.concat([Xp,Xn],axis = 0)
    22. Y = tf.concat([Yp,Yn],axis = 0)
    23. #样本洗牌
    24. data = tf.concat([X,Y],axis = 1)
    25. data = tf.random.shuffle(data)
    26. X = data[:,:2]
    27. Y = data[:,2:]
    28. #可视化
    29. plt.figure(figsize = (6,6))
    30. plt.scatter(Xp[:,0].numpy(),Xp[:,1].numpy(),c = "r")
    31. plt.scatter(Xn[:,0].numpy(),Xn[:,1].numpy(),c = "g")
    32. plt.legend(["positive","negative"]);
    1. ds_train = tf.data.Dataset.from_tensor_slices((X[0:n*3//4,:],Y[0:n*3//4,:])) \
    2. .shuffle(buffer_size = 1000).batch(20) \
    3. .prefetch(tf.data.experimental.AUTOTUNE) \
    4. .cache()
    5. ds_valid = tf.data.Dataset.from_tensor_slices((X[n*3//4:,:],Y[n*3//4:,:])) \
    6. .batch(20) \
    7. .prefetch(tf.data.experimental.AUTOTUNE) \
    8. .cache()

    2,定义模型

    1. Model: "dnn_model"
    2. _________________________________________________________________
    3. Layer (type) Output Shape Param #
    4. =================================================================
    5. dense1 (Dense) multiple 12
    6. _________________________________________________________________
    7. dense2 (Dense) multiple 40
    8. _________________________________________________________________
    9. dense3 (Dense) multiple 9
    10. =================================================================
    11. Total params: 61
    12. Trainable params: 61
    13. Non-trainable params: 0
    14. _________________________________________________________________

    3,训练模型

    1. ### 自定义训练循环
    2. optimizer = optimizers.Adam(learning_rate=0.01)
    3. loss_func = tf.keras.losses.BinaryCrossentropy()
    4. train_loss = tf.keras.metrics.Mean(name='train_loss')
    5. train_metric = tf.keras.metrics.BinaryAccuracy(name='train_accuracy')
    6. valid_loss = tf.keras.metrics.Mean(name='valid_loss')
    7. valid_metric = tf.keras.metrics.BinaryAccuracy(name='valid_accuracy')
    8. @tf.function
    9. def train_step(model, features, labels):
    10. with tf.GradientTape() as tape:
    11. predictions = model(features)
    12. loss = loss_func(labels, predictions)
    13. grads = tape.gradient(loss, model.trainable_variables)
    14. optimizer.apply_gradients(zip(grads, model.trainable_variables))
    15. train_loss.update_state(loss)
    16. train_metric.update_state(labels, predictions)
    17. @tf.function
    18. def valid_step(model, features, labels):
    19. predictions = model(features)
    20. batch_loss = loss_func(labels, predictions)
    21. valid_loss.update_state(batch_loss)
    22. valid_metric.update_state(labels, predictions)
    23. def train_model(model,ds_train,ds_valid,epochs):
    24. for epoch in tf.range(1,epochs+1):
    25. for features, labels in ds_train:
    26. train_step(model,features,labels)
    27. for features, labels in ds_valid:
    28. valid_step(model,features,labels)
    29. logs = 'Epoch={},Loss:{},Accuracy:{},Valid Loss:{},Valid Accuracy:{}'
    30. if epoch%100 ==0:
    31. printbar()
    32. tf.print(tf.strings.format(logs,
    33. (epoch,train_loss.result(),train_metric.result(),valid_loss.result(),valid_metric.result())))
    34. train_loss.reset_states()
    35. valid_loss.reset_states()
    36. train_metric.reset_states()
    37. valid_metric.reset_states()
    38. train_model(model,ds_train,ds_valid,1000)
    1. ================================================================================17:35:02
    2. Epoch=100,Loss:0.194088802,Accuracy:0.923064,Valid Loss:0.215538561,Valid Accuracy:0.904368
    3. ================================================================================17:35:22
    4. Epoch=200,Loss:0.151239693,Accuracy:0.93768847,Valid Loss:0.181166962,Valid Accuracy:0.920664132
    5. ================================================================================17:35:43
    6. Epoch=300,Loss:0.134556711,Accuracy:0.944247484,Valid Loss:0.171530813,Valid Accuracy:0.926396072
    7. ================================================================================17:36:04
    8. Epoch=400,Loss:0.125722557,Accuracy:0.949172914,Valid Loss:0.16731061,Valid Accuracy:0.929318547
    9. ================================================================================17:36:24
    10. Epoch=500,Loss:0.120216407,Accuracy:0.952525079,Valid Loss:0.164817035,Valid Accuracy:0.931044817
    11. ================================================================================17:36:44
    12. Epoch=600,Loss:0.116434008,Accuracy:0.954830289,Valid Loss:0.163089141,Valid Accuracy:0.932202339
    13. ================================================================================17:37:05
    14. Epoch=700,Loss:0.113658346,Accuracy:0.956433,Valid Loss:0.161804497,Valid Accuracy:0.933092058
    15. ================================================================================17:37:25
    16. Epoch=800,Loss:0.111522928,Accuracy:0.957467675,Valid Loss:0.160796657,Valid Accuracy:0.93379426
    17. ================================================================================17:37:46
    18. Epoch=900,Loss:0.109816991,Accuracy:0.958205402,Valid Loss:0.159987748,Valid Accuracy:0.934343576
    19. ================================================================================17:38:06
    20. Epoch=1000,Loss:0.10841465,Accuracy:0.958805501,Valid Loss:0.159325734,Valid Accuracy:0.934785843

    3-3,高阶API示范 - 图4

    如果对本书内容理解上有需要进一步和作者交流的地方,欢迎在公众号”Python与算法之美”下留言。作者时间和精力有限,会酌情予以回复。

    也可以在公众号后台回复关键字:加群,加入读者交流群和大家讨论。