《PyTorch深度学习实践》7. 处理多维特征的输入

处理多维特征的输入

常见数据格式

  • 每一行是一条记录(Record)
  • 每一列是一个特征/字段(Feature)

image-20200918142954530

Logistic Regression Model

首先演示在数据有多维特征时采用Logistic Regression Model的公式形式:

$\hat{y}^{(i)}=\sigma(\sum_{n=1}^8x_n^{(i)}\cdot\omega_n+b)$

下图是上面公式的矩阵图示,其中$\sigma$为sigmoid函数:

image-20200918144651810

对于右下角的矩阵等式,$N\times8$的那个矩阵可以理解为每一行一个record,每一列一个feature,$N\times1$b矩阵是b广播而来的

8维特征,一层线性模型:

1
2
3
4
5
6
7
8
9
10
11
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear = torch.nn.Linear(8, 1) # 8维输入1维输出,同时可以有N条记录
self.sigmoid = torch.nn.Sigmoid()

def forward(self, x):
x = self.sigmoid(self.linear(x))
return x

model = Model()

其中self.linear=torch.nn.Linear(8,1)是输出为一维线性模型。输出改成其它维度,如改为self.linear=torch.nn.Linear(8,6),模型可视化如下:

image-20200918152718584

多个不同维度的线性层(以激活函数结束)串联在一起,得到一个简单的神经网络:

image-20200918154823946

image-20200918155750697

层越多参数越多,学习能力越强,但学习能力不是越强越好,太强的话会把噪声都学进去了,没有泛化能力

上面的神经网络图示:

image-20200919090443557

示例:Diabetes Prediction

四个步骤:

  • Prepare dataset
  • Design model using Class
    • Inherit from nn.Module
  • Construct loss and optimizer
  • Training cycle
    • forward, backward, update

Prepare dataset

1
2
3
4
5
# 数据集链接: https://pan.baidu.com/s/1Ku5c99yDHNFMt8EJAcF5LA 提取码: n4xh
xy = np.loadtxt('diabetes.csv', delimiter=',', dtype=np.float32) # 也可不解压直接用diabetes.csv.gz
# 不建议用double类型,神经网络一般用float32
x_data = torch.from_numpy(xy[:, :-1])
y_data = torch.from_numpy(xy[:, [-1]]) # 注意-1上有[],这样能保证拿出来的是一个矩阵,否则成向量了

Design model using Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear1 = torch.nn.Linear(8, 6)
self.linear2 = torch.nn.Linear(6, 4)
self.linear3 = torch.nn.Linear(4, 1)
self.sigmoid = torch.nn.Sigmoid() # 注意: 1. 这里的sigmoid与torch.sigmoid()不太一样,
# 后者是一个函数,这里的是一个类
# 2. sigmoid没有需要训练的参数,所以定义一个
# 就行了 sigmoid: 1/(1+e^(-z))
# 如果要换激活函数,如ReLU,可以像这样:
# self.activate = torch.nn.ReLU()

def forward(self, x):
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x)) # 如果前面激活函数用的ReLU,由于ReLU在输入<10时会
# 直接输出0,如果后面算ln可能会出问题,
# 在最后一层要套sigmoid
return x

model = Model()

Construct loss and optimizer

由于是二分类问题,采用了交叉熵作为loss函数,optimizer与之前课程中的选择一致

image-20200918162925437

1
2
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

Training Cycle

1
2
3
4
5
6
7
8
9
10
11
12
13
for epoch in range(100):
# Forward
y_pred = model(x_data) # 注意:这里还没有用mini-batch,而是直接把整个数据集用于训练了,
# 之后讨论DataLoader的用法
loss = criterion(y_pred, y_data)
print(epoch, loss.item())

# Backward
optimizer.zero_grad()
loss.backward()

# Update
optimizer.step()

附:神经网络中经常用到的激活函数

来源:http://rasbt.github.io/mlxtend/user_guide/general_concepts/activation-functions/#activation-functions-for-artificial-neural-networks

img

ReLU在神经网络里面用的比较多,但ReLU不连续

在Colab上运行

课程来源:《PyTorch深度学习实践》完结合集