A、Pytorchはじめとインストール
1.はじめに
PyTorchは成長率TensorFlowと一致深い学習フレームワークのPython言語のリメイクでトーチに基づいています。
2.利点:
- 巧みなオン:numpyのと始めるために、深い学習の基本的な概念を把握します
- 柔軟な簡単なコード:ネットワークを構築することが容易nn.moduleメイクとパッケージ、ダイナミックに基づいて、図のメカニズム、柔軟
- デバッグは簡単:デバッグPyTorchはような単純なPythonのコードをデバッグします
- ドキュメントの仕様:HTTPS://pytorch.org/docs/は、ドキュメントの各バージョンで見つけることができます
- より多くの資源:arXivの新しいアルゴリズムのほとんどは達成していPyTorch
- 開発者およびより:GitHubの上の貢献者(協力者)は1100以上+を持っています
- ツリーバック:フェイスブック、維持・発展
インストール3.:
-
アナコンダ(ミラーUSTCを追加する必要があります)
-
pycharm(インストールディレクトリ\ binフォルダにJetBrainsの-agent.jar、中pycharm64.exe.vmoptionsにコマンドを追加します
-javaagent:安装目录\jetbrains-agent.jar
。再起動ページのActivateを選択します) -
pytorch(を通じて、cuda10.0と対応CuDNNバージョンをインストール
nvcc -V
検証。ログインhttps://download.pytorch.org/whl/torch_stable.html。ダウンロードCU100 /トーチ-1.2.0-cp37- cp37m-win_amd64.whl と対応WHLファイルのtorchvision、仮想環境を作成するには、対応する仮想環境を入力し、PIPのインストールを介して)。最後に、検証の手順を次に示します。import torch print(torch.__version__)
第二に、テンソルの紹介と作成
1.テンソルのプロパティ
0.4.0前に、変数のデータ・タイプトーチ.AU TOG R広告は主に含む、テンソル、自動導出をカプセル化するために使用されます。
- データ:パッケージTエンSOR
- 大学院:の傾きでD
- grad_fn:F UNCンTを作成するエンSORはの自動導出するための鍵であります
- requires_卒業生は:勾配かどうかを示します
- is_葉:葉ノード(テンソル)かどうかを示します
テンソルは、変数のすべての属性と互換性があり、以下の3つを追加した後:
- DTYPE:そのようなトーチ.FloatTensor、torch.cuda.FloatTensorとしてテンソルデータ型、
- 形状:形状テンソルのような(64、3、224、224)
- デバイス:機器、GPU / CPUは、加速するための鍵であるテンソル
2 [作成
A.ダイレクト
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False) # 是否锁页内存
torch.from_numpy(...) # 共享内存,参数同上
B.値に基づいて、
torch.zeros(*size, out=None, dtype=None, layout=torch.strided,device=None, requires_grad=False)
torch.zeros_like(input, dtype=None,layout=None,device=None, requires_grad=False)
torch.ones(...) # 参数同zeros
torch.ones_like(...) # 参数同zeros_like
# 以下函数参数从out起同zeros
torch.full(size, fill_value, ...)
torch.arange(start=0, end, step=1, ...) # step表步长
torch.linspace(start, end, steps=100, ...) # steps表长度 (steps-1)*step=end-start
torch.logspace(start, end, steps=100, base=10.0,...)
torch.eye(n, m=None,..) # 二维,n行m列
確率分布に従ってC.
torch.normal(mean, std, (size,) out=None) # mean, std 均为标量时size表示输出一维张量大小,否则没有size,输出的张量来自于不同分布
torch.randn(*size, out=None, dtype=None, layout=torch.strided,device=None, requires_grad=False) # 标准正太分布
torch.rand(...) # 均匀分布,参数同randn
torch.randint(low=0, high,...) # 均匀整数分布,参数从size同randn
torch.randperm(n,...) # 0到n-1随机排列,参数从out同randn
torch.bernoulli(input, *, generator=None, out=None) # 以input为概率,生成伯努力分布
第三に、線形回帰テンソルの操作
1.テンソル操作
A.スプライシングと分割
torch.cat(tensors, dim=0, out=None)
torch.stack(tensors, dim=0, out=None) # 在新维度上拼接
torch.chunk(input, chunks, dim=0)
torch.split(tensor, split_size_or_sections, dim=0)
B.テンソル指数
torch.index_select(input, dim, index, out=None)
torch.masked_select(input, mask, out=None) # mask为与input同形状的bool
C.テンソル変換
torch.reshape(input, shape)
torch.transpose(input, dim0, dim1) # 交换的两维
torch.t(input)
torch.squeeze(input, dim=None, out=None) # 默认去除所有长度1的维,否则去除指定且长度为1的维
torch.usqueeze(input, dim, out=None)
2.数学
3.線形回帰
結果:
import torch
import matplotlib.pyplot as plt
torch.manual_seed(10)
lr = 0.05 # 学习率 20191015修改
# 创建训练数据
x = torch.rand(20, 1) * 10 # x data (tensor), shape=(20, 1)
y = 2*x + (5 + torch.randn(20, 1)) # y data (tensor), shape=(20, 1)
# 构建线性回归参数
w = torch.randn((1), requires_grad=True)
b = torch.zeros((1), requires_grad=True)
for iteration in range(1000):
# 前向传播
wx = torch.mul(w, x)
y_pred = torch.add(wx, b)
# 计算 MSE loss
loss = (0.5 * (y - y_pred) ** 2).mean()
# 反向传播
loss.backward()
# 更新参数
b.data.sub_(lr * b.grad)
w.data.sub_(lr * w.grad)
# 清零张量的梯度 20191015增加
w.grad.zero_()
b.grad.zero_()
# 绘图
if iteration % 20 == 0:
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-', lw=5)
plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.xlim(1.5, 10)
plt.ylim(8, 28)
plt.title("Iteration: {}\nw: {} b: {}".format(iteration, w.data.numpy(), b.data.numpy()))
plt.pause(0.5)
if loss.data.numpy() < 1:
break
第四に、図のメカニズムの動的計算マップ
1.図の計算
図の計算は二つの主要な要素があり、操作が非環式有向グラフ記述するために使用されている:(ノード、ベクトル、行列、テンソルとして、示すデータ)およびエッジ(Edgeは、そのような添加などの操作を表し、減算畳み込みなど)ジャンクション
:図の計算は、で表されるy = (x+ w) * (w+1)
以下
a = x + w
b = w + 1
y = a * b
各計算グラフに従って構成と勾配テンソルを計算することができます。
- 葉テンソル:テンソルのユーザーが作成し、保存された勾配、無勾配関数
- 非リーフテンソル:計算、バックプロパゲーション勾配のリリースによって得られました。バックプロパゲーションの前にない限り、
a.retain_grd()
例えばx=2 w=1
、算出マップは、によって得られます。
\(DW = \ FRAC {\部分Y} {\部分W} = \ FRAC {\部分Y} {\部分A} \ FRAC {\部分A} {\部分W} + \ FRAC {\部分Y} { \部分B} \ FRAC {\部分B} {\部分W} = B * 1 + * 1 = 1 + W + X + W = 5 \)
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x) # retain_grad()
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward() # 张量内部方法,调用了torch.autograd.backward()
print(w.grad)
テンソル([5])
# 查看叶子结点
print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)
# 查看梯度
print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)
# 查看 grad_fn
print("grad_fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)
is_leaf:
TRUE TRUE FALSE FALSE偽
勾配:
テンソル([5])テンソル([2])なしなしなし
grad_fn:
<0x000001F6AACD7D68でMulBackward0オブジェクト> <0x000001F6C1A52048でAddBackward0オブジェクト> <0x000001F6AABCB0F0でAddBackward0オブジェクト>なしなし
図2のダイナミックな - と同時に運用構造
動的グラフ図対静的 - 基と旅行対の自由運動(調整する柔軟やすいです)
五、autogradおよびロジスティック回帰
1. autograd自動的にストライキ勾配
torch.autograd.backward(tensors,grad_tensors=None,retain_graph=None,create_graph=False)
torch.autograd.grad(outputs,inputs,grad_outputs=None,retain_graph=None,create_graph=False) # 求指定inputs的梯度
パラメータ:
-
retain_graph
図は、複数のために、コンピューティング保存しましたw = torch.tensor([1.], requires_grad=True) x = torch.tensor([2.], requires_grad=True) a = torch.add(w, x) b = torch.add(w, 1) y = torch.mul(a, b) y.backward(retain_graph=True) # print(w.grad) y.backward()
-
grad_tensors
これは、マルチ勾配重みを表しますy0 = torch.mul(a, b) # y0 = (x+w) * (w+1) y1 = torch.add(a, b) # y1 = (x+w) + (w+1) dy1/dw = 2 loss = torch.cat([y0, y1], dim=0) # [y0, y1] loss.backward(gradient=torch.tensor([1., 2.])) print(w.grad) # 1*5+2*2=9
-
create_graph
テンソル出力タプル、微分演算を表します。x = torch.tensor([3.], requires_grad=True) y = torch.pow(x, 2) # y = x**2 grad_1 = torch.autograd.grad(y, x, create_graph=True) # grad_1 = dy/dx = 2x = 2 * 3 = 6 print(grad_1) grad_2 = torch.autograd.grad(grad_1[0], x) # grad_2 = d(dy/dx)/dx = d(2x)/dx = 2 print(grad_2)
(テンソル([6]、grad_fn =
)、)
(テンソル([2]))
注意:
-
グラデーションは自動的にクリアされません。
w = torch.tensor([1.], requires_grad=True) x = torch.tensor([2.], requires_grad=True) for i in range(4): a = torch.add(w, x) b = torch.add(w, 1) y = torch.mul(a, b) y.backward() print(w.grad)
そうでない場合
w.grad.zero_()
、勾配が蓄積されます -
リーフノードの接合に依存し、requires_gradデフォルトはTrueです
print(a.requires_grad, b.requires_grad, y.requires_grad)
真真真
-
リーフノードは、その場で実行することはできません
a = torch.ones((1, )) a = a + torch.ones((1, )) # a存储位置改变,为inplace操作 a += torch.ones((1, ))
w = torch.tensor([1.], requires_grad=True) x = torch.tensor([2.], requires_grad=True) a = torch.add(w, x) b = torch.add(w, 1) y = torch.mul(a, b) w.add_(1) y.backward()
例外RuntimeError:葉の変数卒業生を必要とインプレース操作で使用されてきました。
2.ロジスティック回帰=対数回帰チャンス
モデルのトレーニング手順:
結果:
コード:
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np
torch.manual_seed(10)
# ============================ step 1/5 生成数据 ============================
sample_nums = 100
mean_value = 1.7
bias = 1
n_data = torch.ones(sample_nums, 2)
x0 = torch.normal(mean_value * n_data, 1) + bias # 类别0 数据 shape=(100, 2)
y0 = torch.zeros(sample_nums) # 类别0 标签 shape=(100, 1)
x1 = torch.normal(-mean_value * n_data, 1) + bias # 类别1 数据 shape=(100, 2)
y1 = torch.ones(sample_nums) # 类别1 标签 shape=(100, 1)
train_x = torch.cat((x0, x1), 0)
train_y = torch.cat((y0, y1), 0)
# ============================ step 2/5 选择模型 ============================
class LR(nn.Module):
def __init__(self):
super(LR, self).__init__()
self.features = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.features(x)
x = self.sigmoid(x)
return x
lr_net = LR() # 实例化逻辑回归模型
# ============================ step 3/5 选择损失函数 ============================
loss_fn = nn.BCELoss()
# ============================ step 4/5 选择优化器 ============================
lr = 0.01 # 学习率
optimizer = torch.optim.SGD(lr_net.parameters(), lr=lr, momentum=0.9)
# ============================ step 5/5 模型训练 ============================
for iteration in range(1000):
# 前向传播
y_pred = lr_net(train_x)
# 计算 loss
loss = loss_fn(y_pred.squeeze(), train_y)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 清空梯度
optimizer.zero_grad()
# 绘图
if iteration % 20 == 0:
mask = y_pred.ge(0.5).float().squeeze() # 以0.5为阈值进行分类
correct = (mask == train_y).sum() # 计算正确预测的样本个数
acc = correct.item() / train_y.size(0) # 计算分类准确率
plt.scatter(x0.data.numpy()[:, 0], x0.data.numpy()[:, 1], c='r', label='class 0')
plt.scatter(x1.data.numpy()[:, 0], x1.data.numpy()[:, 1], c='b', label='class 1')
w0, w1 = lr_net.features.weight[0]
w0, w1 = float(w0.item()), float(w1.item())
plot_b = float(lr_net.features.bias[0].item())
plot_x = np.arange(-6, 6, 0.1)
plot_y = (-w0 * plot_x - plot_b) / w1
plt.xlim(-5, 7)
plt.ylim(-7, 7)
plt.plot(plot_x, plot_y)
plt.text(-5, 5, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.title("Iteration: {}\nw0:{:.2f} w1:{:.2f} b: {:.2f} accuracy:{:.2%}".format(iteration, w0, w1, plot_b, acc))
plt.legend()
plt.show()
plt.pause(0.5)
if acc > 0.99:
break