之前我一直使用的是TensorFlow-1.x的版本,雖說靜態圖模式比較繁瑣,但用習慣了之後還是覺得挺不錯的,後來TensorFlow-2.x的版本推出了,聽說採用了Keras的高階API,而且默認使用eager模式,然後我也隨便看了一下構建模型的代碼,第一感覺是跟Pytorch、mxnet好像,如果學習過這兩個DNN框架的朋友們去學TF-2.x的話應該來說比較容易,反正我也不知道到底好不好用,下面我就要像一個小白一樣重新開始學習TensorFlow-2.x了(感覺TF-1.x白學了…)。
先說一下我的機器上的環境,Python-3.6.7、Tensorflow-2.0.2,CUDA-10.0。我在我的機器上配置了兩個環境,一個是TF-1.13.1的環境,一個就是虛擬環境TF-2.0.2的環境,並沒有使用Anaconda,我用過這東西,可能是我不習慣吧,對它實在是折騰不來,後來通過pip配置了虛擬環境。
跟mxnet的教程博文一樣,本篇章與mxnet一一對應,有些理論部分就不講解了。
本章對應的mxnet文章:MXNET深度學習框架-03-採用ndarray和autograd實現線性迴歸
1、生成數據
tf.random.set_seed(99)
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真實權重
true_b = 4.2 # 真實偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =0.1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)
print(features)
1000個2維數據點的結果:
看起來是不是特簡單,直接打印就行了,要在TF-1.X種,還得使用sess.run()方法。
2、繪製散點圖查看數據
def set_figsize(figsize=(3.5, 2.5)):
plt.scatter(features[:, 1], labels, 1) # 第二特徵和標籤的對應關係
plt.show()
set_figsize() #調用function顯示散點圖
結果:
3、讀取數據
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices)
for i in range(0, num_examples, batch_size):
j = indices[i: min(i+batch_size, num_examples)]
yield tf.gather(features, axis=0, indices=j), tf.gather(labels, axis=0, indices=j)
# 取batch數據
for batch_x, batch_y in data_iter(10, features, labels):
print("特徵:",batch_x,"\n","標籤:",batch_y)
break
結果:
4、定義模型參數
w = tf.Variable(tf.random.normal((num_inputs, 1), stddev=0.01))
b = tf.Variable(tf.zeros((1,)))
5、定義模型結構
def linreg(X, w, b):
return tf.matmul(X, w) + b
6、定義損失函數
def squared_loss(y_hat, y):
return (y_hat - tf.reshape(y, y_hat.shape)) ** 2 /2 #爲什麼要除以2?好求導
7、定義小批量隨機梯度下降-SGD
def sgd(params, lr, batch_size, grads):
for i, param in enumerate(params):
param.assign_sub(lr * grads[i] / batch_size)
8、訓練模型
lr = 0.03
num_epochs = 50
net = linreg
loss = squared_loss
batch_size=100
for epoch in range(num_epochs):
train_loss,num_count=0,0
for X, y in data_iter(batch_size, features, labels):
num_count+=1 # 取多少次結束
with tf.GradientTape() as t:
t.watch([w,b])
l = loss(net(X, w, b), y)
grads = t.gradient(l, [w, b])# 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
sgd([w, b], lr, batch_size, grads)
train_loss+=tf.reduce_sum(l).numpy()
print('epoch %d, loss %f' % (epoch + 1, train_loss/num_count))
結果:
9、預測結果:
print(true_w, "",w)
print(true_b, "",b)
結果:
可以看到,預測的結果已經很接近了。
下面放上所有代碼:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import random
#1、生成1000個數據
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真實權重
true_b = 4.2 # 真實偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)
# print(features)
#2、繪製散點圖查看數據
def set_figsize(figsize=(3.5, 2.5)):
plt.scatter(features[:, 1], labels, 1) # 第二特徵和標籤的對應關係
plt.show()
set_figsize() #調用function顯示散點圖
#3、讀取數據
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices)
for i in range(0, num_examples, batch_size):
j = indices[i: min(i+batch_size, num_examples)]
yield tf.gather(features, axis=0, indices=j), tf.gather(labels, axis=0, indices=j)
# 取batch數據
for batch_x, batch_y in data_iter(10, features, labels):
print("特徵:",batch_x,"\n","標籤:",batch_y)
break
#4、定義權重參數
w = tf.Variable(tf.random.normal((num_inputs, 1), stddev=0.01))
b = tf.Variable(tf.zeros((1,)))
#5、定義模型結構
def linreg(X, w, b):
return tf.matmul(X, w) + b
#6、定義損失函數
def squared_loss(y_hat, y):
return (y_hat - tf.reshape(y, y_hat.shape)) ** 2 /2 #爲什麼要除以2?好求導
#7、定義小批量隨機梯度下降-SGD
def sgd(params, lr, batch_size, grads):
for i, param in enumerate(params):
param.assign_sub(lr * grads[i] / batch_size)
#8、訓練
lr = 0.03
num_epochs = 50
net = linreg
loss = squared_loss
batch_size=100
for epoch in range(num_epochs):
train_loss,num_count=0,0
for X, y in data_iter(batch_size, features, labels):
num_count+=1 # 取多少次結束
with tf.GradientTape() as t:
t.watch([w,b])
l = loss(net(X, w, b), y)
grads = t.gradient(l, [w, b])# 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
sgd([w, b], lr, batch_size, grads)
train_loss+=tf.reduce_sum(l).numpy()
print('epoch %d, loss %f' % (epoch + 1, train_loss/num_count))
print(true_w, "",w)
print(true_b, "",b)