You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

431 lines
9.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.3 线性回归的简洁实现"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.4.1\n"
]
}
],
"source": [
"import torch\n",
"from torch import nn\n",
"import numpy as np\n",
"torch.manual_seed(1)\n",
"\n",
"print(torch.__version__)\n",
"torch.set_default_tensor_type('torch.FloatTensor')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.1 生成数据集"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"num_inputs = 2\n",
"num_examples = 1000\n",
"true_w = [2, -3.4]\n",
"true_b = 4.2\n",
"features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float)\n",
"labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b\n",
"labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.2 读取数据"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import torch.utils.data as Data\n",
"\n",
"batch_size = 10\n",
"\n",
"# 将训练数据的特征和标签组合\n",
"dataset = Data.TensorDataset(features, labels)\n",
"\n",
"# 把 dataset 放入 DataLoader\n",
"data_iter = Data.DataLoader(\n",
" dataset=dataset, # torch TensorDataset format\n",
" batch_size=batch_size, # mini batch size\n",
" shuffle=True, # 要不要打乱数据 (打乱比较好)\n",
" num_workers=2, # 多线程来读数据\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([[-0.0163, -1.0072],\n",
" [-0.3554, -0.1807],\n",
" [-1.2406, -2.3683],\n",
" [ 1.3847, 1.9209],\n",
" [-0.7570, -0.3135],\n",
" [ 0.3181, -0.8122],\n",
" [-0.3864, 0.0382],\n",
" [ 1.0939, -0.1225],\n",
" [ 0.7272, 0.4801],\n",
" [ 0.6706, -0.7972]]) \n",
" tensor([7.6005, 4.1017, 9.7864, 0.4568, 3.7355, 7.5675, 3.2881, 6.7967, 4.0404,\n",
" 8.2513])\n"
]
}
],
"source": [
"for X, y in data_iter:\n",
" print(X, '\\n', y)\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.3 定义模型"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LinearNet(\n",
" (linear): Linear(in_features=2, out_features=1, bias=True)\n",
")\n"
]
}
],
"source": [
"class LinearNet(nn.Module):\n",
" def __init__(self, n_feature):\n",
" super(LinearNet, self).__init__()\n",
" self.linear = nn.Linear(n_feature, 1)\n",
"\n",
" def forward(self, x):\n",
" y = self.linear(x)\n",
" return y\n",
" \n",
"net = LinearNet(num_inputs)\n",
"print(net) # 使用print可以打印出网络的结构"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Sequential(\n",
" (linear): Linear(in_features=2, out_features=1, bias=True)\n",
")\n",
"Linear(in_features=2, out_features=1, bias=True)\n"
]
}
],
"source": [
"# 写法一\n",
"net = nn.Sequential(\n",
" nn.Linear(num_inputs, 1)\n",
" # 此处还可以传入其他层\n",
" )\n",
"\n",
"# 写法二\n",
"net = nn.Sequential()\n",
"net.add_module('linear', nn.Linear(num_inputs, 1))\n",
"# net.add_module ......\n",
"\n",
"# 写法三\n",
"from collections import OrderedDict\n",
"net = nn.Sequential(OrderedDict([\n",
" ('linear', nn.Linear(num_inputs, 1))\n",
" # ......\n",
" ]))\n",
"\n",
"print(net)\n",
"print(net[0])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Parameter containing:\n",
"tensor([[0.5347, 0.7057]], requires_grad=True)\n",
"Parameter containing:\n",
"tensor([0.6873], requires_grad=True)\n"
]
}
],
"source": [
"for param in net.parameters():\n",
" print(param)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.4 初始化模型参数"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Parameter containing:\n",
"tensor([0.], requires_grad=True)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from torch.nn import init\n",
"\n",
"init.normal_(net[0].weight, mean=0.0, std=0.01)\n",
"init.constant_(net[0].bias, val=0.0) # 也可以直接修改bias的data: net[0].bias.data.fill_(0)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Parameter containing:\n",
"tensor([[-0.0142, -0.0161]], requires_grad=True)\n",
"Parameter containing:\n",
"tensor([0.], requires_grad=True)\n"
]
}
],
"source": [
"for param in net.parameters():\n",
" print(param)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.5 定义损失函数"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"loss = nn.MSELoss()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.6 定义优化算法"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SGD (\n",
"Parameter Group 0\n",
" dampening: 0\n",
" lr: 0.03\n",
" momentum: 0\n",
" nesterov: False\n",
" weight_decay: 0\n",
")\n"
]
}
],
"source": [
"import torch.optim as optim\n",
"\n",
"optimizer = optim.SGD(net.parameters(), lr=0.03)\n",
"print(optimizer)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# 为不同子网络设置不同的学习率\n",
"# optimizer =optim.SGD([\n",
"# # 如果对某个参数不指定学习率,就使用最外层的默认学习率\n",
"# {'params': net.subnet1.parameters()}, # lr=0.03\n",
"# {'params': net.subnet2.parameters(), 'lr': 0.01}\n",
"# ], lr=0.03)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# # 调整学习率\n",
"# for param_group in optimizer.param_groups:\n",
"# param_group['lr'] *= 0.1 # 学习率为之前的0.1倍"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.7 训练模型"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch 1, loss: 0.000457\n",
"epoch 2, loss: 0.000081\n",
"epoch 3, loss: 0.000198\n"
]
}
],
"source": [
"num_epochs = 3\n",
"for epoch in range(1, num_epochs + 1):\n",
" for X, y in data_iter:\n",
" output = net(X)\n",
" l = loss(output, y.view(-1, 1))\n",
" optimizer.zero_grad() # 梯度清零等价于net.zero_grad()\n",
" l.backward()\n",
" optimizer.step()\n",
" print('epoch %d, loss: %f' % (epoch, l.item()))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, -3.4] tensor([[ 1.9999, -3.4005]])\n",
"4.2 tensor([4.2011])\n"
]
}
],
"source": [
"dense = net[0]\n",
"print(true_w, dense.weight.data)\n",
"print(true_b, dense.bias.data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}