線性不可分二分類問題的神經網絡分類(pytorch實現)

首先生成一個線性不可分數據集

import numpy as np
import matplotlib.pyplot as plt


N = 200

x1 = np.linspace(-1, 1, N)   # (1, 100)
y1 = x1 ** 2 + 0.2 * np.random.rand(N)  # (1, 100)
x1 = np.reshape(x1, (N, 1))  # (100, 1)
y1 = np.reshape(y1, (N, 1))  # (100, 1)

x_c1 = np.concatenate((x1, y1), 1)   # (100, 2)

x2 = np.linspace(0, 2, N)
y2 = -(x2 - 1) ** 2 + 0.2 * np.random.rand(N) + 1.5
x2 = np.reshape(x2, (N, 1))
y2 = np.reshape(y2, (N, 1))

x_c2 = np.concatenate((x2, y2), 1)   # (100, 2)

data_x = np.concatenate((x_c1, x_c2), 0)   # (200, 2)

y_c1 = np.zeros((N, 1))   # (100, 1)
y_c2 = np.ones((N, 1))   # (100, 1)
data_y = np.concatenate((y_c1, y_c2), 0)    # (200, 1)

plt.scatter(x1, y1)
plt.scatter(x2, y2)
plt.show()

圖像如下

接着搭建網絡

import torch.nn as nn
import torch
import torch.utils.data as d
import torch.nn.functional as func


tensor_x = torch.tensor(data_x, dtype=torch.float)
tensor_y = torch.tensor(data_y, dtype=torch.float)
print(tensor_y)

# tensor_x=data, tensor_y=label
data_set = d.TensorDataset(tensor_x, tensor_y)
# shuffle:是否打亂順序
loader = d.DataLoader(
    dataset=data_set,
    batch_size=10,
    shuffle=True
)


class Net(nn.Module):

    def __init__(self):
        super().__init__()
        self.hidden1 = nn.Linear(2, 32)
        self.hidden2 = nn.Linear(32, 16)
        self.hidden3 = nn.Linear(16, 1)

    def forward(self, x):
        x = func.relu(self.hidden1(x))
        x = func.relu(self.hidden2(x))
        x = func.relu(self.hidden3(x))
        return x


net1 = Net()
print(net1)

optimizer = torch.optim.Adam(net1.parameters(), lr=0.01)
loss_func = torch.nn.MSELoss()
loss_list = []

網絡計算圖如下

接下來進行訓練

# training ...
for epoch in range(100):
    for step, (batch_x, batch_y) in enumerate(loader):

        prediction = net1(batch_x)
        loss = loss_func(prediction, batch_y)
        loss_list.append(loss.data.tolist())

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

訓練結果如下

可見收斂了,可以把權值導出來可視化

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pickle


def relu(a):
    return np.maximum(a, 0)


def fun(a, b):
    c = np.array([[a],
                  [b]])
    r1 = relu(w1.dot(c) + b1)
    r2 = relu(w2.dot(r1) + b2)
    r3 = relu(w3.dot(r2) + b3)
    return r3


fig = plt.figure()
ax = Axes3D(fig)
x = np.arange(-1, 2, 0.1)
y = np.arange(-1, 2, 0.1)
X, Y = np.meshgrid(x, y)
N = X.shape[0]
Z = np.zeros((N, N))

for i in range(N):
    for j in range(N):
        Z[i][j] = fun(X[i][j], Y[i][j])

x1 = data_x[:, 0]
y1 = data_x[:, 1]
z1 = data_y
ax.scatter(x1, y1, c='w')

plt.xlabel('x')
plt.ylabel('y')
# ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow')
ax.contourf(X, Y, Z, zdir='z', offset=0, cmap='rainbow')
ax.set_zlim(0, 1)
plt.show()

首先我們來看網絡函數圖像和數據點的關係

可見函數很好的擬合了數據點

加下了我們來看下投影圖

同樣可知神經網絡對這個非線性可分問題做出了較好的分類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章