import tensorflow as tf
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
#數據載入(參考北大公開課--曹老師)
df = pd.read_csv('./dot.csv')
x_data = df[['x1','x2']]
y_data = df['y_c']
#轉爲numpy數組|
x_data = np.array(x_data)
y_data = np.array(y_data).reshape(-1,1)
#數據類型轉化
x_train = tf.cast(x_data,dtype = tf.float32)
y_train = tf.cast(y_data,dtype = tf.float32)
#繪圖時採用標記點color
y_c = [['red' if y else 'blue'] for y in y_train]
#數據拼接
traindb = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(32)
#模型訓練
lr = 0.005 #初始學習率
epochs = 2000 #迭代次數
regularize = 0.03 #正則化因子
#神經網絡模型,輸入層爲n*2,第一層爲2*20,第二層爲20*10,輸出層爲10*1,且第一層與第二層之間增加激活函數,第二層與輸出層之間增加激活函數
#第一層
w1 = tf.Variable(tf.random.truncated_normal([2,20],dtype = tf.float32))
b1 = tf.Variable(tf.random.truncated_normal([20],dtype = tf.float32))
#第二層
w2 = tf.Variable(tf.random.truncated_normal([20,10],dtype = tf.float32))
b2 = tf.Variable(tf.random.truncated_normal([10],dtype = tf.float32))
#第三層
w3 = tf.Variable(tf.random.truncated_normal([10,1],dtype = tf.float32))
b3 = tf.Variable(tf.random.truncated_normal([1],dtype = tf.float32))
#統計loss隨epoch變化
loss_all = []
for epoch in range(epochs):
for step,(x_train,y_train) in enumerate(traindb):
with tf.GradientTape() as tape:
h1 = tf.matmul(x_train,w1) + b1
h1 = tf.nn.relu(h1)
h2 = tf.matmul(h1,w2) + b2
h2 = tf.nn.relu(h2)
y = tf.matmul(h2,w3) + b3
loss_mse = tf.reduce_mean(tf.square(y - y_train))
#計算正則化
loss_regularization = []
loss_regularization.append(tf.nn.l2_loss(w1))
loss_regularization.append(tf.nn.l2_loss(w2))
loss_regularization.append(tf.nn.l2_loss(w3))
loss_regularization = tf.reduce_sum(loss_regularization)
loss = loss_mse + regularize * loss_regularization
#計算loss對各個參數的梯度
variables = [w1,b1,w2,b2,w3,b3]
grads = tape.gradient(loss,variables)
#更新參數
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])
w2.assign_sub(lr * grads[2])
b2.assign_sub(lr * grads[3])
w3.assign_sub(lr * grads[4])
b3.assign_sub(lr * grads[5])
if(epoch % 20 ==0):
loss_all.append(loss)
print('epoch: ',epoch,'lr: ',lr,'loss: ',float(loss))
#模型測試
# 生成測試網格點數據
xx,yy = np.mgrid[-3:3:.04,-3:3:.04]
testdb = tf.cast(np.c_[xx.ravel(),yy.ravel()],dtype = tf.float32)
# probs添加predict值
probs = []
for test in testdb:
h1 = tf.matmul([test],w1) + b1
h1 = tf.nn.relu(h1)
h2 = tf.matmul(h1,w2) + b2
h2 = tf.nn.relu(h2)
y = tf.matmul(h2,w3) + b3
probs.append(y)
probs = np.array(probs).reshape(xx.shape)
#繪製結果
x1 = x_data[:,0]
x2 = x_data[:,1]
plt.scatter(x1,x2,color = np.squeeze(y_c))
contour = plt.contour(xx,yy,probs,levels=[.5])
plt.clabel(contour,fontsize=10,colors='black')
plt.show()
from sklearn import datasets as datasets
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
x, y = make_circles(n_samples=15000, shuffle=True,
noise=0.03, random_state=None, factor=0.6)
plt.scatter(x[:,0], x[:,1], c=y, s=7)
plt.show()
同樣的代碼處理結果如下圖所示: