1.numpy和pytorch实现梯度下降法
2.设定初始值
3.求取梯度
4.在梯度方向上进行参数的更新
5.numpy和pytorch实现线性回归
numpy参考https://blog.csdn.net/xiaoxy97/article/details/83014243
以下为分别采用BGD、SGD、MBGD拟合y=3x_1+4x_2的系数[3, 4]的代码:
import time
import numpy as np
样本数为100条,特征数为二维
def get_data(sample_num=100):
x1 = np.linspace(0, 9, sample_num) #np.linspace等差数列
x2 = np.linspace(4, 13, sample_num)
x = np.concatenate(([x1], [x2]), axis=0).T #数组拼接并转置
y = np.dot(x, np.array([3, 4]).T) #
return x, y
BGD
def bgd(x, y, step_size=0.01, max_iter_count=10000):
w = np.ones((x.shape[1],))
x1 = x[:, 0]
x2 = x[:, 1]
loss = 10
iter_count = 0
while abs(loss) > 0.0001 and iter_count < max_iter_count:
w[0] -= step_size *
np.sum((w[0] * x1 + w[1] * x2 - y) * x1) / x.shape[0]
w[1] -= step_size *
np.sum((w[0] * x1 + w[1] * x2 - y) * x2) / x.shape[0]
loss = np.sum(w[0] * x1 + w[1] * x2 - y)
iter_count += 1
print(“iter_count:%d the loss:%f” % (iter_count, loss))
return w
SGD
def sgd(x, y, step_size=0.01, max_iter_count=10000):
w = np.ones((x.shape[1],))
x1 = x[:, 0]
x2 = x[:, 1]
loss = 10
iter_count = 0
while abs(loss) > 0.00001 and iter_count < max_iter_count:
i = np.random.randint(x.shape[0])
w[0] -= step_size * (w[0] * x1[i] + w[1] * x2[i] - y[i]) * x1[i]
w[1] -= step_size * (w[0] * x1[i] + w[1] * x2[i] - y[i]) * x2[i]
loss = np.sum(w[0] * x1 + w[1] * x2 - y)
iter_count += 1
print(“iter_count:%d the loss:%f” % (iter_count, loss))
return w
MBGD
def msgd(x, y, batch_size, step_size=0.01, max_iter_count=10000):
w = np.ones((x.shape[1],))
x1 = x[:, 0]
x2 = x[:, 1]
loss = 10
iter_count = 0
while abs(loss) > 0.00001 and iter_count < max_iter_count:
i = np.random.randint(x.shape[0], size=batch_size)
w[0] -= step_size *
np.sum((w[0] * x1[i] + w[1] * x2[i] - y[i]) * x1[i]) / batch_size
w[1] -= step_size *
np.sum((w[0] * x1[i] + w[1] * x2[i] - y[i]) * x2[i]) / batch_size
loss = np.sum(w[0] * x1 + w[1] * x2 - y)
iter_count += 1
print(“iter_count:%d the loss:%f” % (iter_count, loss))
return w
if name == ‘main’:
time1 = time.time()
x, y = get_data()
print(bgd(x, y))
print(sgd(x, y))
print(msgd(x, y, 10))
time2 = time.time()
print(time2 - time1)
pytorch
import torch as t
import numpy as np
from matplotlib import pyplot as plt
线性回归
y = 2 * x + 1
生成数据,带噪音
X = np.random.rand(100)*10
Y = 2 * X + 1 + np.random.randn(100)
随机初始化参数
w = t.rand(1,1,requires_grad=True)
b = t.rand(1,1,requires_grad=True)
def model_LR(X,Y,w,b,lr,iters):
x = t.Tensor(X).reshape([-1,1])
y = t.Tensor(Y).reshape([-1,1])
losses = np.zeros(iters)
for i in range(iters):
# forward:计算loss
y_pred = x.mm(w) + b.expand_as(y)
loss = 0.5 * (y_pred - y) ** 2
loss = loss.mean()
losses[i] = loss.item()
# backward:手动计算梯度
loss.backward()
# 更新参数
w.data.sub_(lr * w.grad.data)
b.data.sub_(lr * b.grad.data)
# 梯度清零
w.grad.data.zero_()
b.grad.data.zero_()
return w,b
model_LR(X,Y,w,b,0.01,10000)
6.pytorch实现一个简单的神经网络
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 输入图像channel:1;输出channel:6;5x5卷积核
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 2x2 Max pooling
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# 如果是方阵,则可以只使用一个数字进行定义
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # 除去批处理维度的其他所有维度
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
print(net)