ディープラーニング 06 - 入門から熟練までの pytorch

概要

PyTorch は、Facebook の人工知能研究チームによって開発および保守されている Python ベースのオープンソース機械学習フレームワークです。ディープ ニューラル ネットワーク モデルを構築およびトレーニングするための豊富なツールとインターフェイスのセットを提供します。

PyTorch の主な機能と利点は次のとおりです。

  1. 動的グラフ: PyTorch は、実行時に計算グラフを構築する動的グラフ メカニズムを使用します。これにより、モデルの構築とデバッグがより直観的かつ柔軟になり、複雑な計算プロセスや動的な制御フローをより適切に処理できるようになります。

  2. シンプルかつ明確: PyTorch の API 設計はシンプルかつ明確なので、学習と使用が簡単です。モデルの構築、トレーニング、評価をより簡単かつ効率的に行うための一連の高レベルのインターフェイスを提供します。

  3. 強力な GPU アクセラレーションのサポート: PyTorch は、テンソル演算とモデル トレーニングに GPU を使用して計算を高速化できます。シンプルで使いやすいインターフェイスを提供し、GPU でのアクセラレーションをより便利にします。

  4. 柔軟な拡張機能: PyTorch はカスタム演算子と拡張機能をサポートしているため、ユーザーは独自のモデル コンポーネントと関数を簡単に実装して使用できます。

比較すると、TensorFlow は、Google が開発したもう 1 つの人気のある深層学習フレームワークです。PyTorch と比較した TensorFlow の主な機能と利点は次のとおりです。

  1. 静的グラフ: TensorFlow は静的グラフ メカニズムを使用し、コンパイル時に計算グラフを構築します。これにより、TensorFlow はモデルの実行時にさらに最適化とパフォーマンスの向上を実行できるようになり、大規模で計算量の多いタスクに適したものになります。

  2. クロスプラットフォームのサポート: TensorFlow はさまざまなハードウェアおよびオペレーティング システム上で実行でき、広範な導入サポートを備えています。TensorFlow Serving、TensorFlow Lite、TensorFlow.js などのツールを提供し、モデルのデプロイと移植をより便利にします。

  3. 分散トレーニングのサポート: TensorFlow は、複数のデバイスとコンピューティング ノードでモデル トレーニングを実行できる分散トレーニング機能を提供し、それによってトレーニングを高速化します。

  4. エコシステムとコミュニティ: TensorFlow には大規模なエコシステムとアクティブなコミュニティがあり、モデル ライブラリ、チュートリアル、フォーラムなどの豊富なリソースとサポートを提供します。

一般に、PyTorch と TensorFlow はどちらも優れた深層学習フレームワークであり、それぞれに独自の特性と適用可能なシナリオがあります。PyTorch はラピッド プロトタイピング、動的なコンピューティング プロセス、小規模なタスクに適しており、TensorFlow は大規模で計算量の多いタスクや分散トレーニングに適しています。どのフレームワークを選択するかは、特定のニーズと個人の好みによって異なります。

ニューラル ネットワークを初めて使用する初心者の場合は、まず pytorch を学習することをお勧めします。提供される API は理論的概念に近く、動的図があり、デバッグに便利で、研究に適しています。最近の chargpt の人気により、 Hugging Face の変換には PyTorch を使用します。Hugging Face は自然言語処理 (NLP) モデルとツールを提供するプラットフォームです。その Transformers ライブラリは主に PyTorch に基づいて実装されており、開始するには pytorch の基本的な基礎が必要です。このライブラリは、テキストデータを簡単に変換および加工できる、データの前処理および後処理のための一連の関数を提供します。

環境整備

cuda と cudnn をインストールする

一般に、PC コンピューターまたはサーバーには nvidia グラフィック カードが搭載されており、nvidia-smi コマンドで表示できます。
ここに画像の説明を挿入します
このうち、Python 環境 (バージョン 3.8 以降) については、cuda と cudnn のインストールを参照してください: https://blog.csdn.net/liaomin416100569/article/details/130532993
インストール後、私の cuda バージョンが 11.2 であることがわかります。

pytorchをインストールする

バージョンが下位互換性があることを考慮すると、cuda=11.2 に対応するバージョンの torch をダウンロードする必要はありません。これより前のバージョンで十分かもしれません。そこで、cuda11.1 バージョンをダウンロードすることにしました。
以下は、pytorch の安定バージョンの URL ダウンロード リンクです。必要に応じて、対応する torch バージョンを見つけてダウンロードできます。cu バージョンは GPU バージョン、cu のないものは CPU バージョン、https://download.pytorch.org/whl/torch_stable.html、cu111 を検索して
ここに画像の説明を挿入します
直接選択します

pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html

テストコードを書く

import torch
print(torch.__version__)
#cuda是否可用,如果返回True,表示正常可用gpu
print(torch.cuda.is_available())
print(torch.cuda.device_count())

x1=torch.rand(5,3)
#把x1转换gpu0的tensor
x1=x1.cuda(0)
print(x1)

テスト走行


1.9.1+cu111
True  
1
tensor([[0.5761, 0.7046, 0.2004],
        [0.6030, 0.3285, 0.5602],
        [0.6852, 0.6602, 0.0033],
        [0.4213, 0.7174, 0.0591],
        [0.5276, 0.4181, 0.8665]], device='cuda:0')

ベース

テンソル

PyTorch には、テンソルに加えて、他の多くのデータ型とクラスがあります。一般的な PyTorch データ型とクラスをいくつか示します。

  1. Tensor: Tensor は PyTorch の中核となるデータ構造で、配列に似ており、多次元データを保存および操作できます。

  2. 変数: 変数はテンソルのパッケージであり、自動導出に使用されます。

  3. nn.Module: nn.Module は、PyTorch でニューラル ネットワーク モデルを構築するために使用される基本クラスであり、複数のレイヤーと操作を含めることができます。

  4. nn.Parameter: nn.Parameter は Variable のサブクラスであり、モデルで学習する必要があるパラメーターを定義するために使用されます。

  5. DataLoader: DataLoader はデータをロードするためのユーティリティ クラスで、データのバッチ処理と反復を容易にします。

  6. オプティマイザー: オプティマイザーは、SGD、Adam などのモデルパラメーターを更新するために使用されるアルゴリズムです。

  7. 損失関数: 損失関数は、クロスエントロピー損失、平均二乗誤差など、モデルの予測結果と実際のラベルとの差を測定するために使用されます。

これらは、PyTorch で一般的に使用されるデータ型とクラスの一部であり、深層学習タスクの実装とトレーニングをサポートする豊富な機能を提供します。

意味

import torch as t
import numpy as np
#构建5*3数组,只是分配了空间未初始化
result=t.Tensor(5,3)
print(result)
#这里产生个0-1之间的tensor张量,并且初始化
x1=t.rand(5,3)
y1=t.rand(5,3)
print(x1)
print(x1.size())
result=x1+y1
print(result)

numpy 変換

#产生5个1的一维数组tensor转换成numpy
print(t.ones(5).numpy())
#将numpy数组转换为tensor
print(t.from_numpy(np.array([2,2,2,])))

数学関数

乱数

乱数の生成に使用できる一般的な PyTorch 関数をいくつか示します。

  1. torch.randn(size, dtype=None, device=None)- 標準正規分布からランダムなサンプルを返します。指定されたサイズのテンソルを返します。各要素は標準正規分布から独立して描画されます。sizeテンソルの形状はパラメータを指定することで指定できます。

例:


x = torch.randn(3, 3)
print(x)
  1. torch.rand(size, dtype=None, device=None)- 一様分布からランダムなサンプルを返します。各要素が一様分布から独立して描画される、指定されたサイズのテンソルを返します。sizeテンソルの形状はパラメータを指定することで指定できます。

例:


x = torch.rand(3, 3)
print(x)`
  1. torch.randint(low, high, size, dtype=None, device=None)- 離散一様分布からランダムな整数を返します。各要素が一様分布から独立して描画される、指定されたサイズのテンソルを返します。lowおよびパラメータを指定することで値の範囲を指定できますhigh

例:


x = torch.randint(0, 10, (3, 3))
print(x)
  1. torch.normal(mean, std, size, dtype=None, device=None)- 正規分布からランダムなサンプルを返します。各要素が正規分布から独立して描画される、指定されたサイズのテンソルを返します。パラメータと パラメータを指定することで、正規分布の平均値と標準偏差を指定meanできます。std

例:


x = torch.normal(0, 1, (3, 3))
print(x)

これらの関数は、PyTorch で乱数を生成するのに役立ちます。ニーズに応じて適切な機能をお選びください。

演算機能

一般的に使用される数学的計算関数
もちろん、ここに PyTorch で一般的に使用される数学的関数のリストがあり、それぞれに簡単な説明と簡単な呼び出し例が付いています。

  • torch.abs(input): 入力テンソルの絶対値を返します。例: torch.abs(torch.tensor([-1, 2, -3]))。
  • torch.sqrt(input): 入力テンソルの平方根を返します。例: torch.sqrt(torch.tensor([4, 9, 16]))。
  • torch.exp(input): 入力テンソルの指数関数を計算します。例: torch.exp(torch.tensor([1, 2, 3]))。
  • torch.log(input): 入力テンソルの自然対数を計算します。例: torch.log(torch.tensor([1, 10, 100]))。
  • torch.sin(input): 入力テンソルのサインを計算します。例: torch.sin(torch.tensor([0, math.pi/2, math.pi]))。
  • torch.cos(input): 入力テンソルのコサインを計算します。例: torch.cos(torch.tensor([0, math.pi/2, math.pi]))。
  • torch.tan(input): 入力テンソルの正接を計算します。例: torch.tan(torch.tensor([0, math.pi/4, math.pi/2]))。
  • torch.sigmoid(input): 入力テンソルのシグモイド関数を計算します。例: torch.sigmoid(torch.tensor([0, 1, 2]))。
  • torch.relu(input): ReLU 活性化関数、つまり max(0, input) を適用します。例: torch.relu(torch.tensor([-1, 0, 1]))。
  • torch.softmax(input, dim): 指定された次元で入力テンソルの Softmax 関数を計算します。例: torch.softmax(torch.tensor([[1, 2], [3, 4]]), dim=1)。
  • torch.mean(input): 入力テンソルの平均を計算します。例: torch.mean(torch.tensor([1, 2, 3]))。
  • torch.sum(input): 入力テンソルの合計を計算します。例: torch.sum(torch.tensor([1, 2, 3]))。
  • torch.max(input): 入力テンソルの最大値を返します。例: torch.max(torch.tensor([1, 2, 3]))。
  • torch.min(input): 入力テンソルの最小値を返します。例: torch.min(torch.tensor([1, 2, 3]))。
  • torch.argmax(input): 入力テンソルの最大値のインデックスを返します。例: torch.argmax(torch.tensor([1, 2, 3]))。
  • torch.argmin(input): 入力テンソルの最小値のインデックスを返します。例: torch.argmin(torch.tensor([1, 2, 3]))。
  • torch.sort(input): 入力テンソルをソートします。例: torch.sort(torch.tensor([3, 1, 2]))。
  • torch.clamp(input, min, max): 入力テンソルの値を指定された範囲にクランプします。例: torch.clamp(torch.tensor([1, 2, 3]), min=2, max=3)。
  • torch.round(input): 入力テンソルを丸めます。例: torch.round(torch.tensor([1.1, 2.4, 3.6]))。
  • torch.floor(input): 切り捨てて、入力テンソル以下の最大の整数を返します。例: torch.floor(torch.tensor([1.1, 2.4, 3.6]))。

行列処理関数

以下は、PyTorch で一般的に使用される 20 個の行列処理関数のリストとその説明です。

  • torch.mm(): 2 つの行列の積を計算します。
    例: torch.mm(torch.tensor([[1, 2], [3, 4]]), torch.tensor([[5], [6]])) は tensor([[17], [39] を返します) ]])

  • torch.matmul(): 2 つのテンソルの行列積を計算します。
    例: torch.matmul(torch.tensor([[1, 2], [3, 4]]), torch.tensor([[5], [6]])) は tensor([[17], [39] を返します) ]])

  • torch.transpose(): 入力テンソルの転置を返します。
    例: torch.transpose(torch.tensor([[1, 2], [3, 4]]), 0, 1) は tensor([[1, 3], [2, 4]]) を返します

  • torch.mm(): 行列とベクトルの積を計算します。
    例: torch.mm(torch.tensor([[1, 2], [3, 4]]), torch.tensor([5, 6])) は tensor([17, 39]) を返します

  • torch.trace(): 行列のトレースを返します。
    例: torch.trace(torch.tensor([[1, 2], [3, 4]])) は tensor(5) を返します

  • torch.det(): 行列の行列式を計算します。
    例: torch.det(torch.tensor([[1, 2], [3, 4]])) は tensor(-2) を返します

  • torch.svd(): 行列の特異値分解を実行します。
    例: torch.svd(torch.tensor([[1, 2], [3, 4]])) は (tensor([[-0.4046, -0.9145], [-0.9145, 0.4046]]) を返します、tensor([ 5.4645, 0.3650])、テンソル([[-0.5760, -0.8174], [-0.8174, 0.5760]]))

  • torch.eig(): 行列の固有値と固有ベクトルを計算します。
    例: torch.eig(torch.tensor([[1, 2], [3, 4]])) は (tensor([[0.3723, 0.0000], [5.6277, 0.0000]]), tensor([])) を返します。

  • torch.inverse(): 行列の逆行列を計算します。
    例: torch.inverse(torch.tensor([[1, 2], [3, 4]])) は tensor([[-2.0000, 1.0000], [ 1.5000, -0.5000]]) を返します

  • torch.diag(): 行列の対角要素を返します。
    例: torch.diag(torch.tensor([[1, 2], [3, 4]])) は tensor([1, 4]) を返します

  • torch.diag_embed(): 1 次元テンソルを対角行列に変換します。
    例: torch.diag_embed(torch.tensor([1, 2, 3])) は tensor([[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [ [0, 0, 0]、[0, 2, 0]、[0, 0, 0]]、[[0, 0, 0]、[0, 0, 0]、[0, 0, 3]] ])

  • torch.einsum(): アインシュタインの合計規則を実装します。
    例: torch.einsum('ij,jk->ik', torch.tensor([[1, 2], [3, 4]]), torch.tensor([[5, 6], [7, 8] ])) は tensor([[19, 22], [43, 50]]) を返します

  • torch. flatten(): 入力テンソルを平坦化します。
    例: torch. flatten(torch.tensor([[1, 2], [3, 4]])) は tensor([1, 2, 3, 4]) を返します

  • torch.cat(): 指定された次元に沿ってテンソルを連結します。
    例: torch.cat((torch.tensor([[1, 2]]), torch.tensor([[3, 4]])), dim=0) は tensor([[1, 2], [3] を返します) 、4]])

  • torch.stack(): 新しい次元に沿ってテンソルをスタックします。
    例: torch.stack((torch.tensor([1, 2]), torch.tensor([3, 4])), dim=0) は tensor([[1, 2], [3, 4]] を返します) )

  • torch.split(): 指定された次元に沿ってテンソルを分割します。
    例: torch.split(torch.tensor([[1, 2, 3, 4]]), 2, dim=1) returns (tensor([[1, 2]]), tensor([[3, 4] ]))

  • torch.chunk(): テンソルを指定された数のチャンクに分割します。
    例: torch.chunk(torch.tensor([[1, 2, 3, 4]]), 2, dim=1) returns (tensor([[1, 2]]), tensor([[3, 4] ]))

  • torch.reshape(): テンソルの形状を変更します。
    例: torch.reshape(torch.tensor([[1, 2, 3, 4]]), (2, 2)) は tensor([[1, 2], [3, 4]]) を返します

  • torch.squeeze(): テンソルのサイズ 1 の次元を圧縮します。
    例: torch.squeeze(torch.tensor([[[1], [2]]])) は tensor([1, 2]) を返します

  • torch.unsqueeze(): 指定された位置にサイズ 1 の新しい次元を挿入します。
    例: torch.unsqueeze(torch.tensor([1, 2]), dim=1) は tensor([[1], [2]] を返します)

  • torch.view は、テンソルの形状を変更する、つまりテンソルの形状を変更するために使用される PyTorch の関数です。これは、NumPy の reshape 関数と同様に機能します。
    x = torch.tensor([1, 2, 3, 4, 5, 6])
    y = x.view(2, 3)

  • torch.permute 関数は、テンソルの次元順序を再配置するために使用される PyTorch の関数です。その役割は、テンソルの次元を交換または再構成することです。
    次の例では、元のテンソル x の次元の順序は (2, 3, 4) です。permute(2, 0, 1) を使用すると、次元の順序は (4, 2, 3) に並べ替えられ、新しいテンソルは、次元 2 が関数インデックス 0 次元に置き換えられ、0 次元のものは 1 に置き換えられ、1 次元のものは 2 に置き換えられることを意味します。

        import torch
        x = torch.randn(2, 3, 4)  # 创建一个形状为(2, 3, 4)的张量
        x_permuted = x.permute(2, 0, 1)  # 将维度顺序重新排列为(4, 2, 3)
        print(x_permuted.shape)  # 输出: torch.Size([4, 2, 3])

自動グラデーション

深層学習アルゴリズムは基本的にバックプロパゲーションを通じて導関数を計算し、PyTorch の Autograd モジュールはこの機能を実装します。Tensor 上のすべての操作に対して、Autograd は微分を自動的に提供し、微分を手動で計算する複雑なプロセスを回避します。

PyTorch では、Tensor と Variable の両方で勾配を見つけることができますが、いくつかの違いがあります。

PyTorch の古いバージョンでは、Variable は Tensor データとこの Tensor に関する勾配情報を含む Tensor パッケージです。PyTorch の新しいバージョンでは、Variable は非推奨になり、Tensor を直接使用することが公式に推奨されています。

PyTorch の Tensor オブジェクトには .requires_grad 属性があり、デフォルトは False です。True に設定すると、この Tensor の勾配を計算することになります。バックプロパゲーションを実行して勾配を計算する場合、.requires_grad=True を持つすべての Tensor は勾配情報を保持します。

計算に Tensor を使用する場合、 .backward() メソッドを呼び出して、この Tensor に対する相対的な勾配を計算できます。グラデーション情報は .grad 属性に保存されます。

したがって、Variable の役割は Tensor の .requires_grad 属性に置き換えることができ、新しいバージョンの PyTorch では、勾配計算に Tensor を直接使用することが公式に推奨されています。
変数とテンソルには主に 3 つの属性が含まれます。

  • data: 計算結果に対応する Tensor を保存します。
  • grad: データと同じ形状のデータに対応する勾配 (テンソル) を保存します。
  • grad fn: Function オブジェクトを指します。この関数は、入力の勾配を逆伝播するために使用されます (requires_grad=True)
x=Variable(t.from_numpy(np.array([[1,2],[2,4]],dtype=float)),requires_grad=True)
print("张量x=",x)
y=x.sum()
print("输出y",y)
print("输出y的梯度",y.grad) #注意结果是y,所以y是没有梯度的,y进行反向传播,可以求导x的导数
print("y的反向梯度函数",y.grad_fn)
print("y的数据",y.data)
# 因为y=x[0][0]+x[0][1]+x[1][0]++x[1][1],可以认为四个数是四个变量,比如求每个变量的导数
# 假设是y=x1+x2+x3+x4  x1是自变量,x1的导数就是1,同理x2的导数也是1,最后就得到了4个1
# 注意每个点都有个梯度
y.backward() #反向传播计算梯度
print(x.grad)

出力

张量x= tensor([[1., 2.],
        [2., 4.]], dtype=torch.float64, requires_grad=True)
输出y tensor(9., dtype=torch.float64, grad_fn=<SumBackward0>)
输出y的梯度 None
y的反向梯度函数 <SumBackward0 object at 0x0000025F8F2C8C10>
y的数据 tensor(9., dtype=torch.float64)
x的梯度 tensor([[1., 1.],
        [1., 1.]], dtype=torch.float64)

場合

ケース 1: x 2 ∗ exx^2*e^xを計算するバツ2ex導関数

#计算x**2*e^x导数
#dx=2*x*e^x+x**2*e^x
#定义fx的函数逻辑
def f(x):
    return x**2*t.exp(x)
#我们预先知道他的梯度函数是
def graddx(x):
    return 2*x*t.exp(x)+x**2*t.exp(x)
#生成一个3*3随机矩阵,求梯度
x=Variable(t.rand(3,3),requires_grad=True)
print(graddx(x))
#使用反向传播求梯度
y=f(x)
y.backward(t.ones(y.size()))
print(x.grad)

ケース 2: 自動勾配降下法を使用して最適な直線を近似する

#使用autograd计算梯度,来实现线性回归
import torch as t
from torch.autograd import Variable as V
import matplotlib.pyplot as plot
t.manual_seed(42)
# 使用自动梯度实现线性回归
x=t.randn(100,1)
y=3*x+2+t.randn(100,1) #实际值上加上一些随机噪点
plot.plot(x,y,'.')
plot.show()
w=V(t.randn(1,1),requires_grad=True)
b=V(t.randn(1),requires_grad=True)
def fx(x):
   return t.mm(x,w)+b
#损失函数   
def lossf(y_pre,y):
    return t.mean((y_pre-y)**2)
#训练100次,100次梯度下降,计算到最小损失时的w和b
w_gra_last,b_gra_last=0,0
for epoch in range(100):
    y_pre=fx(x)
    loss=lossf(y_pre,y)
    loss.backward()
    w_gra=w.grad.data
    b_gra=b.grad.data
    w_gra_last=w_gra.clone()
    b_gra_last=b_gra.clone()
    #如果梯度小于某个值直接退出
    if t.abs(w_gra)<=1e-8 and t.abs(b_gra)<=1e-8:
        break;
    learn_rate=0.01
    #注意w.sub_是不行的因为w是requires_grad=True,需要后面的参数都是设置为:requires_grad=True
    #所以只能是更新他的data
    w.data.sub_(w_gra*learn_rate)
    b.data.sub_(b_gra*learn_rate)
    #注意梯度清零,否则会累加
    w.grad.data.zero_()
    b.grad.data.zero_()
# w_gra_last是张量,item输出标量
print(epoch,w_gra_last.item(),b_gra_last.item())    
y_pre=fx(x)  
plot.plot(x,y,'.')
plot.plot(x.data.numpy(),y_pre.data.numpy())
plot.show()

ここに画像の説明を挿入します

計算グラフ

PyTorch の計算グラフは、計算操作を記述するために使用される有向非巡回グラフ (DAG) です。PyTorch では、計算グラフは動的であり、コードの実行時に構築されます。

計算グラフの主な機能は、自動微分と勾配最適化のための計算操作のプロセスを記録および管理することです。計算グラフを構築することにより、PyTorch はすべての計算操作を追跡および記録して、自動導出を実現できます。これにより、バックプロパゲーションを簡単に実行し、深層学習でモデル パラメーターを最適化できるようになります。

計算グラフを使用する利点は次のとおりです。

  1. 自動導出: PyTorch は、計算グラフに基づいてバックプロパゲーションに必要な勾配計算コードを自動的に生成できるため、手動導出のプロセスが簡素化されます。
  2. 動的グラフの柔軟性: 計算グラフは動的に構築され、必要に応じて動的に変更および調整できるため、モデル構造と計算プロセスがより柔軟で変更可能になります。
  3. 視覚化とデバッグ: 計算グラフを視覚化することで、モデルの実行プロセスを理解してデバッグし、モデルの動作をよりよく理解して説明することができます。

つまり、PyTorch の計算グラフは、柔軟で効率的な自動導出機能を提供する強力なツールであり、深層学習モデルのトレーニングと最適化をより便利かつ迅速に行うことができます。

#打印计算图
import torch
from torchviz import make_dot

# 定义一个简单的计算图
w= torch.randn(1, requires_grad=True)
b= torch.randn(1, requires_grad=True)
x = torch.randn(1, requires_grad=True)
y = w*x + b

# 使用make_dot函数绘制计算图,图上的数字只是代表数据的维度
dot = make_dot(y, params={'x': x, 'w': w, 'b': b}, show_attrs=True, show_saved=True)
dot.render(filename='compute_graph', format='png')

現在実行中のディレクトリに compute_graph.png が表示されます。
ここに画像の説明を挿入します
逆導出のプロセスを分析します。
たとえば、式 z=wx+b は、y=wx と z=y+b に分解できます。計算図を図 3 に示します。 -5. 図の MUL と ADD は両方とも演算子であり、w、x、b は変数です。
ここに画像の説明を挿入します
上記の有向非巡回グラフでは、X と b はリーフ ノードであり、通常、これらのノードはユーザー自身によって作成され、他の変数には依存しません。z はルート ノードと呼ばれ、計算グラフの最終目標です。連鎖ルールを使用すると、各リーフ ノードの勾配を簡単に見つけることができます。
ここに画像の説明を挿入します
計算グラフを使用すると、図に示すような計算グラフの逆伝播を利用して、上記の連鎖導出を自動的に完了することができます。
ここに画像の説明を挿入します

トーチビジョンモジュール

torchvision は、コンピューター ビジョン タスク用の多くのユーティリティ関数と事前トレーニングされたモデルを提供する PyTorch の拡張ライブラリです。これには、一般的に使用されるデータセット、データ変換、モデルアーキテクチャ、画像処理方法、その他の機能が含まれます。

torchvision の主な機能は次のとおりです。

  1. データ セット: torchvision は、MNIST、CIFAR-10、ImageNet など、一般的に使用されるコンピューター ビジョン データ セットを多数提供します。これらのデータセットは、モデルのトレーニングとテストに便利に使用できます。

  2. データ変換: torchvision は、画像に対するトリミング、スケーリング、反転、正規化、その他の操作など、データの前処理と強化のための一連の変換関数を提供します。これらの変換関数は、モデル トレーニングのニーズを満たすためにデータセット内のサンプルに柔軟に適用できます。

  3. 事前トレーニングされたモデル: torchvision は、AlexNet、VGG、ResNet などのいくつかの古典的なコンピューター ビジョン モデルを統合します。これらの事前トレーニング済みモデルは、特定のタスクの転移学習に直接使用したり、パフォーマンス比較のベースライン モデルとして使用したりできます。

  4. 画像処理: torchvision は、画像フィルタリング、エッジ検出、色変換など、一般的に使用されるいくつかの画像処理方法も提供します。これらのメソッドは、画像処理および強化タスクに使用できます。

つまり、torchvision は PyTorch に豊富なコンピューター ビジョン機能とツールを提供し、コンピューター ビジョン タスクの開発と実装プロセスを大幅に簡素化できます。

変換

torchvision は、ランダムなトリミング、反転、回転、正規化など、データ拡張のためのいくつかの一般的な変換を提供します。これらの変換は、データのロード時に画像に適用して、モデルの一般化と堅牢性を向上させることができます。
トーチ内のすべての変換は次のとおりです。

  1. Compose: 複数の変換を結合します。
  2. ToTensor: PIL イメージまたは NumPy 配列をテンソルに変換します。
  3. ToPILImage: テンソルを PIL イメージ オブジェクトに変換します。
  4. 正規化: 各チャネルの値から平均を減算し、標準偏差で割ることによってテンソルを正規化します。
  5. サイズ変更: 画像のサイズを変更します。
  6. CenterCrop: 画像の一部を中央で切り抜きます。
  7. RandomCrop: 画像の一部をランダムにトリミングします。
  8. RandomResizeCrop: 画像をランダムにトリミングしてサイズ変更します。
  9. FiveCrop: 5 つの異なる位置で画像をトリミングします。
  10. TenCrop: 画像を 10 個の異なる位置でトリミングします。
  11. Randomhorizo​​ntalFlip: 画像をランダムに水平方向に反転します。
  12. RandomVerticalFlip: 画像をランダムに垂直方向に反転します。
  13. RandomRotation: 画像をランダムに回転します。
  14. RandomAffine: 画像をランダムにアフィン変換します。
  15. ColorJitter: 画像の明るさ、コントラスト、彩度、色相をランダムに調整します。
  16. RandomGrayscale: 画像をランダムにグレースケールに変換します。
  17. RandomErasing: 画像の一部をランダムに消去します。
  18. RandomChoice: 適用する変換をランダムに選択します。
  19. RandomApply: 変換をランダムに適用します。
  20. RandomOrder: 変換の順序をランダムにシャッフルします。

これらは torch のすべての変換であり、ニーズに応じて画像データを処理するための適切な変換を選択できます。
よく使用される変換関数とサンプル コードをいくつか示します。

  1. サイズ変更: 画像のサイズを変更します
from PIL import Image

# 定义一个Resize变换,将图像调整为指定大小
resize = transforms.Resize((256, 256))

# 读取图像
image = Image.open('image.jpg')

# 对图像进行Resize变换
resized_image = resize(image)
  1. ToTensor: 画像を Tensor 型に変換します
from PIL import Image

# 定义一个ToTensor变换,将图像转换为Tensor类型
to_tensor = transforms.ToTensor()

# 读取图像
image = Image.open('image.jpg')

# 对图像进行ToTensor变换
tensor_image = to_tensor(image)
  1. 正規化: 画像を正規化します
from PIL import Image

# 定义一个Normalize变换,将图像进行归一化
normalize = transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])

# 读取图像
image = Image.open('image.jpg')

# 对图像进行Normalize变换
normalized_image = normalize(image)

transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])の機能は、値を -1 から 1 の間に正規化するのではなく、入力データを平均 0、標準偏差 1 の範囲に正規化することです。標準化の目的は、モデルのトレーニングと最適化を向上させるために、データに同様のスケールを持たせることです。
特定の点 (100、150、200) の標準化プロセスは次のとおりです。
1. 各チャネルの平均を計算します: (100 + 150 + 200) / 3 = 150
2. 各チャネルの標準偏差を計算します: sqrt (((100-150)^2 + (150-150)^2 + (200-150)^2) / 3) = sqrt((2500 + 0 + 2500) / 3) ≈ 50 3. それぞれの
値チャネルの値は正規化されます: (100-150)/50 = -1、(150-150)/50 = 0、(200-150)/50 = 1。したがって、正規化された点は (-1, 0, 1) となります
。 )。
なお、これは単純な例であり、実際には、標準偏差を計算する際には、1 点の平均値と標準偏差ではなく、データセット全体の平均値と標準偏差が使用されます。

  1. RandomCrop: 画像をランダムにトリミングします。
from PIL import Image

# 定义一个RandomCrop变换,随机裁剪图像
random_crop = transforms.RandomCrop((224, 224))

# 读取图像
image = Image.open('image.jpg')

# 对图像进行RandomCrop变换
cropped_image = random_crop(image)
  1. Randomhorizo​​ntalFlip: 画像をランダムに水平方向に反転します。
from PIL import Image

# 定义一个RandomHorizontalFlip变换,随机水平翻转图像
random_horizontal_flip = transforms.RandomHorizontalFlip(p=0.5)

# 读取图像
image = Image.open('image.jpg')

# 对图像进行RandomHorizontalFlip变换
flipped_image = random_horizontal_flip(image)

変換モジュールでこれらの関数を使用すると、モデルのトレーニング時に使用する画像を簡単に前処理および強化できます。torchvision.transforms.Compose以下のように、複数の変換を組み合わせて画像に適用するには、通常、transforms 関数をパラメーターとして関数に渡す必要があることに注意してください。

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

データセット

一般的に使用されるコンピューター ビジョン データセットの多くは、torchvision ライブラリで提供されています。torchvision ライブラリでサポートされているいくつかの一般的なデータセットのリストを次に示します。

  1. MNIST: 手書きの数字画像のデータセット。
  2. FashionMNIST: ファッション商品の画像データセット。
  3. CIFAR10: 10 のカテゴリを含むカラー画像データ セット。
  4. CIFAR100: 100 個の細分カテゴリを含むカラー画像データ セット。
  5. SVHN: デジタル画像を含むストリートビュー データセット。
  6. ImageNet: 100 万を超えるオブジェクト カテゴリを含むカラー画像データセット。
  7. COCO: オブジェクト検出および画像セグメンテーション タスク用の複数のオブジェクト カテゴリを含むカラー画像データセット。

上記のデータ セットに加えて、torchvision は、DataLoader、ImageFolder などのデータ セットのロードと前処理のためのいくつかの補助関数とクラスも提供します。

データローダー

以下はCIFAR10をロードする例です。

import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import Dataset,DataLoader
import torch as t
import numpy as np
#加载训练数据50000条
train_dataset=datasets.CIFAR10(root="./data",train=True,transform=transforms.ToTensor(),download=True)
#测试数据集10000条
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transforms.ToTensor())
#打印数据集的维度
print(train_dataset.data.shape,test_dataset.data.shape)
#打印数据集的标签
print(len(train_dataset.targets))
#torchvision.datasets.cifar.CIFAR10
print(type(train_dataset))
#torchvision.datasets.vision.VisionDataset
print(type(train_dataset).__bases__)

datasets.CIFAR10 は、root で指定されたディレクトリにデータセットを自動的にダウンロードしないことに注意してください。ダウンロードが非常に遅い場合は、コンソールによって出力されたパスをダウンロードし、./data ディレクトリにドロップしてオフラインでロードできます。

DataLoader は、PyTorch にデータをロードするためのユーティリティ クラスです。カスタム データ セットを反復可能なデータ ローダーにラップして、バッチ処理、シャッフル、並列ロードなどの操作を容易にすることができます。以下は、DataLoader のいくつかの一般的なパラメータの詳細な説明です。

  • dataset : ロードするデータセット。から継承したtorch.utils.data.Datasetカスタム データセット クラスのインスタンス、またはtorchvision.datasets.ImageFolder既存の PyTorch データセット クラス ( など) のインスタンスにすることができます。

  • batch_size : 各バッチ内のサンプルの数。デフォルト値は 1 です。通常、適切なバッチ サイズはモデルとデバイス メモリに基づいて選択されます。

  • shuffle : 各エポックの前にデータをシャッフルするかどうか (順序をランダムにシャッフルします)。デフォルト値は False です。シャッフルによりトレーニングのランダム性が向上し、モデルがデータ内のパターンをより適切に学習できるようになります。

  • サンプラー: データ サンプリング戦略を定義するために使用されるサンプラー。サンプラーが指定されている場合、シャッフル パラメーターは無視されます。一般的に使用されるサンプラーには、torch.utils.data.RandomSampler(ランダム サンプリング) とtorch.utils.data.SequentialSampler(順次サンプリング) が含まれます。

  • バッチ_sampler : バッチレベルのデータサンプリング戦略を定義するために使用されるサンプラー。batch_sampler が指定されている場合、batch_size、shuffle、sampler パラメーターは無視されます。一般的に使用されるバッチ サンプラーには、 が含まれますtorch.utils.data.BatchSampler

  • num_workers : データのロードに使用される子プロセスの数。デフォルト値は 0 で、これはメインプロセスにデータをロードすることを意味します。コンピュータの CPU コア数とデータ読み込みのパフォーマンス要件に基づいて、適切な値を選択できます。

  • Collat​​e_fn : サンプルのリストをバッチ テンソルに変換する関数。デフォルトでは、デフォルトの照合関数が使用されます。この関数は、サンプルが Tensor または Numpy 配列であると想定し、それらをバッチにスタックします。データセットから返されたサンプルのタイプや形状が異なる場合、それを処理するために照合関数をカスタマイズできます。

  • pin_memory : データを CUDA 固定メモリにロードするかどうか。デフォルト値は False です。トレーニングに GPU を使用する場合、pin_memory を True に設定するとデータ転送が高速化できますが、追加のメモリを占有します。

  • drop_last : データセットのサイズがバッチ サイズで割り切れない場合に、最後の不完全なバッチを削除するかどうか。デフォルト値は False です。トレーニング中は、不完全なバッチによって引き起こされるエラーを回避するために、これは通常 True に設定されます。

  • timeout : データローダーがデータを待機するタイムアウト (秒単位)。デフォルト値は 0 で、タイムアウト制限がないことを意味します。データのロードに時間がかかる場合は、より大きなタイムアウトを設定できます。

  • work_init_fn : 各データローダーの子プロセスの初期化関数。各子プロセスのランダム シードまたはその他の初期化操作を設定するために使用できます。

これらのパラメータは、特定のニーズに応じて調整および構成して、より効率的かつ便利なデータのロードを実現できます。DataLoader は、
ロードされたデータ セットを (バッチ、チャネル、高さ、幅) の形式に変換します。PyTorchでは画像データは一般的にCHW(チャンネル、高さ、幅)の順になります。DataLoader は、ロードされた画像データを (バッチ、チャネル、高さ、幅) の形式に変換します。
ここで、バッチは一度にロードされる画像の数を表します。このデータ形式は、PyTorch の畳み込みニューラル ネットワークの入力要件を満たしています。
torchvision.datasets.vision.VisionDataset はこれらを複雑に処理します。

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 使用数据加载器进行迭代,一批次64条,64条一个循环
for batch in train_loader:
    input_data, labels = batch
    print(input_data.shape)
    break; 

出力: torch.Size([64, 3, 32, 32])

カスタム データセット

私が作成したデータセットは次元変換を受けませんでした。

class MyDs(Dataset):
    def __init__(self,data,label):
        self.data=data
        self.label=label
    def __len__(self):
        return len(self.data)
    def __getitem__(self, index):
        return self.data[index],self.label[index]
ds=MyDs([1,2,3,4],[0,1,1,1])
dsLoader=DataLoader(ds,batch_size=2,shuffle=True)
for input,label in dsLoader:  #四条数据分成了2批,循环两次
    print(input,label)

nnモジュール

nn.モジュール

nn.Moduleこれは、PyTorch のすべてのニューラル ネットワーク モジュールの基本クラスです。これはカスタム ニューラル ネットワーク モジュールを構築するためのコア コンポーネントであり、いくつかの基本的な機能とプロパティを提供します。

以下にnn.Moduleいくつかの重要なプロパティとメソッドを示します。

  • parameters(): トレーニングする必要があるモジュール内のパラメータのイテレータを返します。
  • named_parameters(): トレーニングする必要があるモジュール内のパラメータとその名前のイテレータを返します。
  • children(): モジュール内のすべてのサブモジュールの反復子を返します。
  • named_children(): モジュール内のすべてのサブモジュールとその名前のイテレータを返します。
  • to(device): モジュールを指定したデバイス (CPU や GPU など) に移動します。
  • train(): モジュールをトレーニング モードに設定し、 とBatchNorm同等Dropoutのレイヤーのトレーニング動作を有効にします。
  • eval(): モジュールを評価モードに設定し、層BatchNormDropout等しい層のトレーニング動作を無効にします。
  • forward(input): モジュールの順伝播ロジックを定義し、入力を受信して​​出力を返します。

さらに、nn.Moduleモジュールの初期化とパラメータ管理のためにいくつかのメソッドが提供されています。

  • __init__(): モジュールパラメータとサブモジュールを初期化するために使用されるコンストラクタ。
  • zero_grad(): モジュール内のすべてのパラメータの勾配をゼロに設定します。
  • apply(fn): 指定された関数をモジュールとサブモジュールに再帰的に適用します。
  • state_dict(): すべてのパラメータとバッファを含む、モジュールの現在の状態辞書を返します。
  • load_state_dict(state_dict): モジュールのパラメータとバッファを復元するために使用される、指定された状態辞書をロードします。

クラスを継承することでnn.Module、カスタム ニューラル ネットワーク モジュールを簡単に構築し、PyTorch が提供する多くの関数を使用してモジュールのパラメーター、ステータス、計算ロジックを管理できます。

モジュールを使用して完全に接続されたレイヤーをカスタマイズする

import torch as t;
import torch.nn as nn
class Linear(nn.Module):
    def __init__(self,input_feature,out_feature):
        nn.Module.__init__(self)
        #nn.Prameter是自动算梯度的
        self.w=nn.Parameter(t.randn(input_feature,out_feature))
        self.b=nn.Parameter(t.randn(out_feature))
    def forward(self,x):
        return x.mm(self.w)+self.b
    
layer=Linear(4,1)
rtn=layer(t.randn(3,4))
rtn.backward(t.ones(rtn.size()))  # 计算梯度
print(layer.w.grad)  # 获取w的梯度
print(layer.b.grad)  # 获取b的梯度

CNN

ニューラル ネットワーク処理では、通常、画像マトリックスのチャネルが幅と高さよりも前に配置されます。この表現は、「チャネルファースト」または「NCHW」表現と呼ばれます。この表記法では、行列の次元は (バッチ サイズ、チャネル数、高さ、幅) の順序になっています。

たとえば、RGB カラー イメージの場合、その行列表現は (1、3、H、W) の順に次元を持ちます。1 はバッチ サイズ (一度に処理されるイメージの数を表し、行数を表します) です。 )、3 はチャネル数 (3 つの RGB チャネルを表します)、H は画像の高さ、W は画像の幅です。pytorch はこのメソッドを使用します。

代替の表現は「チャネル最後」または「NHWC」表現で、行列の次元が順番に並んでいます (バッチ サイズ、高さ、幅、チャネル数)。ただし、チャネルファースト表記法は、tensorflow が使用する畳み込み演算の計算方法とより一貫しているため、より一般的です。

画像処理層

PyTorch は、画像処理のための一連のレイヤーと関数を提供します。一般的に使用される画像処理レイヤーをいくつか示します。

  1. nn.Conv2d: 畳み込み層。画像内の特徴を抽出するために使用されます。
  2. nn.MaxPool2d: 最大プーリング層。特徴マップの空間次元を削減するために使用されます。
  3. nn.AvgPool2d: 平均プーリング層。特徴マップの空間次元を削減するために使用されます。
  4. nn.BatchNorm2d: バッチ正規化レイヤー。トレーニングを高速化し、モデルの堅牢性を向上させるために使用されます。
  5. nn.ReLU: ReLU 活性化関数層。非線形性を導入するために使用されます。
  6. nn.Linear: 畳み込み層の出力を最終的な分類または回帰結果にマッピングするために使用される完全接続層。
  7. nn.Dropout2d: オーバーフィッティングを軽減するために使用される 2 次元のドロップアウト レイヤー。
  8. nn.Upsample: アップサンプリング レイヤー。特徴マップの空間次元を増やすために使用されます。
  9. nn.Softmax: ソフトマックス関数レイヤー。マルチカテゴリー分類問題の確率計算に使用されます。

これらのレイヤーに加えて、PyTorch は、畳み込み演算torch.nn.functional.conv2d、プーリング演算、torch.nn.functional.max_pool2dトリミング、回転、スケーリングなどのその他の一般的に使用される画像処理関数など、画像処理のためのいくつかの関数も提供します。

これらのレイヤーと関数は、畳み込みニューラル ネットワーク (CNN) などの画像処理モデルの構築に使用できます。torch.nn.function は結果の計算にのみ使用され、nn パッケージの関数は勾配の計算に使用できます。ニューラルネットワークバッグを構築するときのnn。

畳み込みニューラル ネットワークの各層の概念については、https://blog.csdn.net/liaomin416100569/article/details/130597944?spm=1001.2014.3001.5501 を参照してください。

nn.Conv2d

nn.ConvPyTorch で畳み込み層を定義するために使用されるクラスで、パラメータは次のとおりです。

  • in_channels: 入力テンソルのチャネル数。
  • out_channels: 畳み込み層によって出力されるチャネルの数は、畳み込みカーネルの数でもあります。
  • kernel_size: コンボリューション カーネルのサイズ。整数または (3, 3) などのタプルにすることができます。
  • stride: 畳み込み演算のステップ サイズ。デフォルトは 1 です。
  • padding: 入力テンソルのエッジの周囲を 0 でパディングするレイヤーの数。デフォルトは 0 です。
  • dilation: コンボリューション カーネル要素間の間隔。デフォルトは 1 です。
  • groups: 入力テンソルを畳み込みのために複数のグループに分割します。デフォルトは 1 です。
  • bias: オフセット項目を使用するかどうか。デフォルトは True です。

以下に例を示します。

import torch.nn as nn

# 创建一个卷积层
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1)

## 打印卷积层的参数
print(conv)

出力は次のとおりです。

Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

上記のコードは、入力チャネル番号 3、出力チャネル番号 (ニューロンの数) 64、畳み込みカーネル サイズ 3x3、ストライド 1、およびパディング層番号 1 の畳み込み層を作成します。

in_channels は入力テンソルのチャネル数を表し、入力テンソルの次元としても理解できます。畳み込みニューラル ネットワークでは、入力テンソルの次元は通常、画像のチャネル数を指します。たとえば、RGB 画像の場合、画像は赤、緑、青の 3 つのチャネルで構成されているため、チャネル数は 3 になります。グレースケール イメージの場合、イメージにはチャネルが 1 つしかないため、チャネル数は 1 です。

nn.Conv を使用して畳み込み層を作成する場合、畳み込み層が入力テンソルの次元と一致するように、入力テンソルのチャネル数に従って in_channels パラメーターを設定する必要があります。

Conv2d の stride パラメータは、スライド時のコンボリューション カーネルのストライド サイズを表します。ステップ サイズの機能は、出力特徴マップのサイズを制御することです。具体的には、ストライドが 1 の場合、
コンボリューション カーネルは一度に 1 ピクセルずつスライドし、ストライドが 2 の場合、コンボリューション カーネルは一度に 2 ピクセルずつスライドします。
ストライドの 2 つの次元は、それぞれ画像の行方向と列方向のストライド サイズを表します。提供した例では、ステップ サイズは (1, 1) です。これは、畳み込みカーネルが画像の行方向と列方向に一度に 1 ピクセルずつスライドすることを意味します。

Conv2d のパディング パラメーターは、入力画像の周囲に追加されるパディングのサイズを示します。パディングの役割は、畳み込み演算中に出力特徴マップのサイズを入力特徴マップのサイズと同じに保つか、必要に応じて調整することです。

#################学习卷积
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import torch.nn as nn
import torch as t
#预处理模块
from PIL import Image
image=Image.open("./images/2023_6_30.jpg")
# plt.imshow(image)
# plt.show()
"""
这是一个用于边缘检测的卷积核。在这个卷积核中,中心元素是1,
表示当前位置的像素值对边缘检测有贡献,而周围的元素都是-0.1111,
表示对边缘检测没有贡献。这样的卷积核可以帮助我们提取图像中的垂直边缘特征。
"""
kernel=t.Tensor(
        [[-0.1111, -0.1111, -0.1111],
        [-0.1111,  1.0000, -0.1111],
        [-0.1111, -0.1111, -0.1111]],
)
kernel=t.ones(3,3)/-9
kernel[1][1]=1
#转换成灰度图,通道数变成1了
image=image.convert("L")
#转换成张量
imageTensor=transforms.ToTensor()(image)
print(imageTensor.shape)
#在第0个维度添加一个一维表示批次数据
input=imageTensor.unsqueeze(0)
print("输入形状",input.shape)
layer=nn.Conv2d(1,1,(3,3),bias=False)
# 定义输入张量shape为(batch_size, channels, height, width)
layer.weight.data=kernel.view(1,1,3,3)
output=layer(input)
plt.imshow(transforms.ToPILImage()(output.squeeze(0)),cmap="gray")
plt.show()
#每个卷积核(3×3)与原始的输入图像(480×479)进行卷积,这样得到的 feature map(特征图)大小为(480-3+1)×(479-3+1)= 478×477
print("输出形状",output.shape)

元の画像
ここに画像の説明を挿入します
出力:
torch.Size([1, 480, 479])
入力形状 torch.Size([1, 1, 480, 479])
出力形状 torch.Size([1, 1, 478, 477])
ここに画像の説明を挿入します

nn.AvgPool2d および nn.MaxPool2d

上記の畳み込みグラフがプールされています

plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置全局字体为SimHei
#平均池化(AvgPool)
pool=nn.AvgPool2d(kernel_size=2, stride=2)
#池化层478×477经过(2,2)池化后=(478/2=239,477/2=238)
poolOuput=pool(output)
print(poolOuput.shape)
plt.title("平均池化")
plt.imshow(transforms.ToPILImage()(poolOuput.squeeze(0)),cmap="gray")
plt.show()
#最大化池
pool=nn.MaxPool2d(kernel_size=2, stride=2)
#池化层478×477经过(2,2)池化后=(478/2=239,477/2=238)
poolOuput=pool(output)
print(poolOuput.shape)
plt.title("最大池化")
plt.imshow(transforms.ToPILImage()(poolOuput.squeeze(0)),cmap="gray")
plt.show()

出力
ここに画像の説明を挿入します
ここに画像の説明を挿入します

nn.リニア

nn.LinearPyTorch で線形変換を定義するために使用されるクラスです。これはnn.Moduleのサブクラスであり、ニューラル ネットワークの層を構築するために使用されます。

nn.Linear2 つのパラメータ:in_featuresとを受け入れout_features、それぞれ入力フィーチャのサイズと出力フィーチャのサイズを表します。これは、shape の学習可能な重み行列( in_features,out_features)と、shape の学習可能なバイアス ベクトルを自動的に作成します(out_features,)

#注意全连接是特征连接是是改变最后一维的特征数的,在pytorch图片批量处理后最后需要进行view操作来降低维度到二维。
arr=t.randn((3,4)) 
print(arr)
result=nn.Linear(4,5)
#全连接就是一个输入数据点乘(输入数据维度,输出数据维度)最后得到一个(输入数据行数,输出数据维度)的数组
print(result(arr))

nn.BatchNorm2d

BatchNorm2d は、2 次元畳み込み層の出力をバッチ正規化するために使用される操作です。その計算プロセスは次のとおりです。

入力の次元が [batch_size, num_channels, height, width] であると仮定します。ここで、batch_size はバッチ サイズを表し、num_channels はチャネル数を表し、高さと幅は特徴マップの高さと幅を表します。

  1. 各チャネルの平均と分散を計算します。

    • 各チャネルについて、そのチャネルの現在のバッチ内のすべてのサンプルの特徴マップの平均と分散を計算します。
    • 平均の計算: 平均 = sum(x) / N、ここで、x は現在のチャネルの特徴マップ値、N はバッチ サイズです。
    • 分散の計算: var = sum((x - 平均)^2) / N。
  2. チャネルごとに、次のように正規化します。

    • 現在のチャネル上の各サンプルについて、特徴マップの値は、平均を減算し、標準偏差 (分散の平方根) で割ることによって正規化されます。
    • 正規化された特徴マップは次のとおりです。 y = (x - 平均) / sqrt(var + eps)。ここで、eps はゼロによる除算を避けるための小さな数です。
  3. チャンネルごとに、ズームとパンを行います。

    • 正規化された各特徴マップについて、特徴マップは、学習可能なスケーリング係数 (スケール) を乗算し、学習可能な変換係数 (シフト) を追加することによってスケーリングおよび変換されます。
    • スケーリングと変換後の特徴マップは、y = ガンマ * y + ベータです。ここで、ガンマとベータは学習可能なパラメーターです。

最後に、BatchNorm2d 操作の出力は、正規化され、スケーリングされ、変換された特徴マップです。

この利点は、ニューラル ネットワークのトレーニングを高速化し、モデルの収束および汎化能力を向上させ、学習率に対する感度を下げることができることです。

"""
具体来说,nn.BatchNorm2d是应用在卷积层之后、激活函数之前的操作,其目的是对每个特征通道的数据进行归一化。
它通过对每个特征通道的数据进行标准化,使得数据的均值为0,方差为1。这样做的好处是可以防止梯度消失或爆炸的问题,
并且有助于加速模型的收敛速度。
除此之外,nn.BatchNorm2d还具有正则化的效果,可以减少模型的过拟合。它通过引入额外的可学习参数,实现了对每个特征通道的平移和缩放操作,以便网络可以自行学习数据的适当分布。
"""
arr=t.randint(0,10,(1,1,2,2)).float()#一批次一个通道,高是2,宽是2
print(arr)
result=nn.BatchNorm2d(num_features=1)
#全连接就是一个输入数据点乘(输入数据维度,输出数据维度)最后得到一个(输入数据行数,输出数据维度)的数组
print(result(arr))

出力:

tensor([[[[9., 1.],
          [8., 9.]]]])
tensor([[[[ 0.6727, -1.7191],
          [ 0.3737,  0.6727]]]], grad_fn=<NativeBatchNormBackward>)

nn.レル

nn.ReLUは、入力内のすべての負の値をゼロに変更し、正の値を変更しないままにする PyTorch のアクティベーション関数です。具体的には、入力テンソル x の場合、nn.ReLU関数は次のように計算されます。

ReLU(x) = max(0, x)

arr=t.randint(0,10,(1,1,2,2)).float()#一批次一个通道,高是2,宽是2
#首先进行归一化,归一化后会有负数的部分
batchNorm2d=nn.BatchNorm2d(num_features=1)
result=batchNorm2d(arr)
print("归一化",result)
relu=nn.ReLU()
#全连接就是一个输入数据点乘(输入数据维度,输出数据维度)最后得到一个(输入数据行数,输出数据维度)的数组
print("relu结果",relu(result))

出力:

归一化 tensor([[[[ 0.2773, -1.3867],
          [ 1.3867, -0.2773]]]], grad_fn=<NativeBatchNormBackward>)
relu结果 tensor([[[[0.2773, 0.0000],
          [1.3867, 0.0000]]]], grad_fn=<ReluBackward0>)

nn.Dropout2d

nn.Dropout2d は、トレーニング プロセス中に指定された確率で入力テンソルの各チャネルの各要素をドロップします。破棄された要素はゼロに設定されますが、保持された要素は必要な値を維持するためにスケーリングされます。
このランダムな削除操作は、トレーニング プロセス中の過剰適合を軽減し、モデルの汎化能力を強化するのに役立ちます。ドロップの確率は、nn.Dropout2d のパラメータによって制御できます。
テストプロセス中、すべての要素は保持され、破棄されないことに注意してください。nn.Dropout2d は通常、畳み込みニューラル ネットワークで使用され、畳み込み層または完全接続層の後に配置して、ネットワークがデータに適応しやすくすることができます。

arr=t.randint(0,10,(1,1,4,4)).float()#一批次一个通道,高是2,宽是2
drop=nn.Dropout2d()
newArr=drop(arr)
print(newArr)

出力

tensor([[[[ 8.,  8., 12., 12.],
          [10., 12.,  6., 12.],
          [ 0.,  4., 12., 16.],
          [ 4.,  4., 18., 10.]]]])

nn.ソフトマックス

nn.Softmax は、softmax 関数の出力を計算するために使用される PyTorch の関数です。ソフトマックス関数は通常、元のカテゴリ スコアを確率分布に変換する、多分類問題のニューラル ネットワークで使用されます。

PyTorch では、nn.Softmax を 1 次元または 2 次元のテンソルに適用できます。1D テンソルの場合、テンソル内の各要素に対してソフトマックス演算を実行し、入力テンソルと同じ形状のテンソルを返します。2D テンソルの場合、指定された次元の各行に対してソフトマックス演算を実行します。

ソフトマックス関数の計算式は以下のとおりです。

ソフトマックス ( x _ i ) = exp ( x _ i ) / sum ( exp ( x _ j ) ) ソフトマックス(x\_i) = exp(x\_i) / sum(exp(x\_j))so f t max ( x _ i ) _=e x p ( x _ i ) / sum ( e x p ( x _ j ) ) _

其中, x _ i x\_i x_iは元のカテゴリ スコア、exp は指数関数、sum はすべてのカテゴリスコアの合計です

ソフトマックス関数の出力は、各クラスの確率値が 0 ~ 1 の確率分布であり、すべてのクラスの確率の合計は 1 になります。これは、確率に基づいて最も可能性の高いクラスを選択するために、複数分類の問題で便利に使用できます。

PyTorch では、nn.Softmax 関数を使用してネットワークの出力を処理し、分類結果を取得できます。

arr=t.randint(0,10,(1, 1, 4, 4)).float()#一批次一个通道,高是2,宽是2
print(arr)
#注意在哪个维度上的和等于1,比如一个4维的(维度从0开始),(1, 1, 4, 4)如果你从0维上,取出0维第一行数据/0维上所有数据行,因为只有一行所有永远都是1
#如果是第3维上,总共有4个数据,也就是这四个数之和等于1
#Softmax2D==nn.Softmax(dim=1)
softmax2d=nn.Softmax(dim=3)
newArr=softmax2d(arr)
print(newArr)

t.manual_seed(10)
arr=t.randint(0,10,(1, 2, 4, 4)).float()#一批次2个通道,高是2,宽是2
softmax2d=nn.Softmax2d()
newArr=softmax2d(arr)
print(arr)
print(newArr)

出力

tensor([[[[7., 5., 2., 0.],
          [3., 0., 8., 1.],
          [6., 8., 8., 4.],
          [2., 6., 3., 5.]]]])
tensor([[[[8.7490e-01, 1.1841e-01, 5.8950e-03, 7.9781e-04],
          [6.6846e-03, 3.3281e-04, 9.9208e-01, 9.0466e-04],
          [6.2840e-02, 4.6433e-01, 4.6433e-01, 8.5045e-03],
          [1.2755e-02, 6.9639e-01, 3.4671e-02, 2.5619e-01]]]])
tensor([[[[7., 5., 2., 7.],
          [2., 5., 7., 2.],
          [1., 5., 6., 3.],
          [1., 0., 6., 3.]],

         [[4., 0., 6., 2.],
          [8., 9., 2., 0.],
          [9., 9., 4., 4.],
          [9., 4., 4., 5.]]]])
tensor([[[[9.5257e-01, 9.9331e-01, 1.7986e-02, 9.9331e-01],
          [2.4726e-03, 1.7986e-02, 9.9331e-01, 8.8080e-01],
          [3.3535e-04, 1.7986e-02, 8.8080e-01, 2.6894e-01],
          [3.3535e-04, 1.7986e-02, 8.8080e-01, 1.1920e-01]],

         [[4.7426e-02, 6.6929e-03, 9.8201e-01, 6.6929e-03],
          [9.9753e-01, 9.8201e-01, 6.6929e-03, 1.1920e-01],
          [9.9966e-01, 9.8201e-01, 1.1920e-01, 7.3106e-01],
          [9.9966e-01, 9.8201e-01, 1.1920e-01, 8.8080e-01]]]])

nn.シーケンシャル

nn.Sequentialと はnn.ModuleList、ニューラル ネットワーク モジュールを結合するための PyTorch の 2 つのコンテナです。

  1. nn.Sequential

    • nn.Sequentialモジュールがコンテナに追加された順序で実行される順序付けされたコンテナです。
    • Sequential コンテナーは、Sequential オブジェクトのコンストラクターでモジュールのリストを渡すか、.add_module()メソッドを介してモジュールを 1 つずつ追加することによって作成できます。
    • nn.Sequential各モジュールに入力と出力が 1 つだけある単純なシーケンシャル モデルに適しています。
  2. nn.ModuleList

    • nn.ModuleListは、任意の数のモジュールを順不同で含めることができるコンテナです。
    • ModuleList コンテナは、ModuleList オブジェクトのコンストラクターでモジュールのリストを渡すか、.append()メソッドを介してモジュールを 1 つずつ追加することによって作成できます。
    • nn.ModuleListモジュール間に複数の入力と出力がある可能性があるカスタム接続や複雑なモデル構造に最適です。

要約すると、nn.Sequential単純な逐次モデルには適していますが、nn.ModuleListカスタム結合や複雑なモデル構造には適していません。実際の使用においては、モデルの構造やニーズに応じて適切なコンテナを選択できます。
nn.Sequential を使用して多層パーセプトロンをカスタマイズする

import torch as t
import torch.nn as nn
#实现一个多层感知器,多层感知器(Multilayer Perceptron, MLP)的隐藏层的特征数就是神经元的个数
class MulPerceptron(nn.Module):
    def __init__(self,input_feature,hidden_feature,out_feature):
        nn.Module.__init__(self)
        #Sequential会将上一层的输出作为下层的输入
        self.model=nn.Sequential(
            nn.Linear(input_feature,hidden_feature),
            nn.ReLU(),
            nn.Linear(hidden_feature,out_feature)
        )
    def forward(self,x):
        #隐藏层进行一次全连接得到(行,hidden_feature)数据矩阵
        return self.model(x);
        
mp=MulPerceptron(784,512,1)
result=mp(t.randn(200,784))
print(result)

最後に、(200,1) の結果が出力されます。

損失関数

PyTorch は、一般的に使用される一連の損失関数を提供します。ここでは、いくつかの一般的な損失関数とその使用例を示します。

  1. nn.MSELoss (平均二乗誤差損失関数):

    予測値と真の値の間の平均二乗誤差を計算する回帰タスクに使用されます。

    loss_fn = nn.MSELoss() loss = loss_fn(output, target)

  2. nn.CrossEntropyLoss (クロスエントロピー損失関数):

    予測クラスと真のクラス間のクロスエントロピー損失を計算するための複数分類タスクに使用されます。

    loss_fn = nn.CrossEntropyLoss() loss = loss_fn(output, target)

  3. nn.BCELoss (2 クラスのクロスエントロピー損失関数):

    予測確率と真のラベル間のバイナリ クロスエントロピー損失を計算するためのバイナリ分類タスクに使用されます。

    loss_fn = nn.BCELoss() loss = loss_fn(output, target)

  4. nn.BCEWithLogitsLoss (2 クラスのクロスエントロピー損失関数、シグモイド関数と組み合わせたもの):

    バイナリ分類タスクに使用され、シグモイド関数の演算と組み合わせて、バイナリ クロスエントロピー損失を計算する際の数値安定性の問題を回避できます。

    loss_fn = nn.BCEWithLogitsLoss() loss = loss_fn(output, target)

  5. nn.NLLLoss (負の対数尤度損失関数):

    予測されたクラスの負の対数尤度損失を計算する、複数分類タスクに使用されます。

    loss_fn = nn.NLLLoss() loss = loss_fn(output, target)

これは PyTorch で利用できる損失関数のほんの一部であり、さまざまなタスクやアプリケーション シナリオに利用できる他の損失関数があります。特定のニーズに基づいて、モデルのトレーニングと最適化に適切な損失関数を選択できます。

平均二乗誤差

平均二乗誤差 (MSE) は、回帰問題で一般的に使用される損失関数です。予測値と真の値の間の二乗差の平均を測定します。

特定の予測値と真の値に対して、MSE は次のように計算されます。

MSE = (1/n) * Σ(y_pred - y_true)^2

このうち、n はサンプル数、y_pred は予測値、y_true は真の値です。

MSE の値が小さいほど、予測値と真の値の差が小さくなり、モデルのパフォーマンスが向上します。勾配降下法などの一般的に使用される最適化アルゴリズムは、MSE を最小化することでモデルのパラメーターを調整し、モデルの精度を向上させます。

x=t.randn(100,1)
y=3*x+2+t.randn(100,1) #实际值上加上一些随机噪点
y_pre=3*x+2
plot.plot(x,y,'.')
plot.plot(x,y_pre)
plot.show()
#使用均方误差计算损失值
criterion=nn.MSELoss()
loss=criterion(y,y_pre)
print(loss)

クロスエントロピー

以下は、nn.CrossEntropyLossクロスエントロピー計算プロセスの使用例と詳細な説明です。

import torch.nn as nn

# 假设有4个样本,每个样本有3个类别的预测结果
# 真实标签为[2, 1, 0, 2]
# 预测结果为一个3维张量,每一维表示对应类别的预测概率
outputs = torch.tensor([[0.1, 0.2, 0.7],
                        [0.6, 0.3, 0.1],
                        [0.8, 0.1, 0.1],
                        [0.3, 0.5, 0.2]])

labels = torch.tensor([2, 1, 0, 2])

# 创建交叉熵损失函数
loss_fn = nn.CrossEntropyLoss()

# 计算损失
loss = loss_fn(outputs, labels)

print(loss)

出力は次のとおりです。

tensor(0.8025)

クロスエントロピーは、2 つの確率分布間の類似性を測定する一般的に使用される損失関数です。分類タスクでは通常、モデルの予測結果を確率分布として表示します。各カテゴリには対応する確率があります。

上の例では 4 つのサンプルがあり、各サンプルには 3 つのカテゴリの予測結果があります。outputsは 3 次元テンソルであり、各次元は対応するカテゴリの予測確率を表します。たとえば、outputs[0]これは 3 つのカテゴリの最初のサンプルの予測確率を表し、それぞれ 0.1、0.2、0.7 です。

labelsは、各サンプルの真のクラス ラベルを表す 1 次元テンソルです。たとえば、labels[0]最初のサンプルの真のクラス ラベルが 2 であることを意味します。

クロスエントロピー損失関数の計算プロセスは次のとおりです。

  1. まず、各サンプルについて、予測確率と真のラベルに基づいて、対応するカテゴリの予測確率を計算する必要があります。

    上の例では、最初のサンプルの予測確率は [0.1, 0.2, 0.7] で、真のラベルは 2 です。予測確率内の真のラベルに対応する値 (0.7) を取り出すだけで済みます。

  2. 次に、各サンプルの予測確率を対数変換します。つまり、各予測確率の自然対数を計算します。

    上の例では、最初のサンプルの対数変換された予測確率は log(0.7) です。

  3. 次に、対数変換された予測確率を合計し、サンプル数で割って平均クロスエントロピー損失を取得します。

    上の例では 4 つのサンプルがあるため、対数変換された予測確率を合計して 4 で割ると、平均クロスエントロピー損失が得られます。

最後に、平均クロスエントロピー損失をモデルの損失として取得し、それをモデルのトレーニングと最適化のプロセスで使用します。nn.CrossEntropyLossPyTorch では、ソフトマックス演算と対数変換の計算を自動的に実行するクロスエントロピー損失を計算する関数を使用できます。

オプティマイザ

torch.optim最適化アルゴリズムに使用される PyTorch のモジュールです。損失関数を最小限に抑えるためにニューラル ネットワーク モデルのパラメーターを更新するためのさまざまな最適化アルゴリズムの実装を提供します。

PyTorch では、オプティマイザー オブジェクトを作成してモジュールを使用しますtorch.optimこのオプティマイザー オブジェクトは、ニューラル ネットワーク モデルのパラメーターを更新するために使用されます。

torch.optimモジュールで一般的に使用される最適化アルゴリズムは次のとおりです。

  1. SGD (確率的勾配降下法): 確率的勾配降下法アルゴリズムは、最も基本的な最適化アルゴリズムの 1 つです。これは、パラメーターの損失関数の勾配を計算し、学習率に基づいてパラメーターを更新することによって機能します。これはtorch.optim.SGDクラスを通じて達成できます。

  2. Adam (適応モーメント推定): Adam は、Momentum と RMSprop の利点を組み合わせた適応最適化アルゴリズムです。運動量と二乗勾配の指数関数的に重み付けされた移動平均を使用して、学習率を適応的に調整します。これはtorch.optim.Adamクラスを通じて達成できます。

  3. Adagrad (適応勾配): Adagrad は、各パラメーターに学習率を割り当て、パラメーターの履歴勾配の二乗和に基づいて学習率を適応的に調整する適応最適化アルゴリズムです。これはtorch.optim.Adagradクラスを通じて達成できます。

  4. RMSprop (二乗平均平方根伝播): RMSprop は、指数関数的に重み付けされた移動平均を使用して学習率を適応的に調整する適応型最適化アルゴリズムでもあります。学習率を勾配の二乗和の平方根で割ることによって、学習率をスケールします。これはtorch.optim.RMSpropクラスを通じて達成できます。

これらの最適化アルゴリズムは、対応するオプティマイザー オブジェクトを作成し、ニューラル ネットワーク モデルのパラメーターやその他のハイパーパラメーターを渡すことによって使用できます。たとえば、次のコードは、SGD 最適化アルゴリズム (擬似コード) の使用方法を示しています。

import torch
import torch.optim as optim

# 创建神经网络模型
model = MyModel()

# 创建优化器对象,学习率为0.001
optimizer = optim.SGD(model.parameters(), lr=0.001)

# 在每个训练迭代中,使用优化器更新模型的参数
optimizer.zero_grad()  # 清零梯度
output = model(input)  # 前向传播
loss = criterion(output, target)  # 计算损失
loss.backward()  # 反向传播
optimizer.step()  # 更新参数

上記のコードでは、model.parameters() はニューラル ネットワーク モデルのすべての学習可能なパラメーターを返します。これらのパラメーターはオプティマイザーによって更新されます。optimizer.zero_grad() メソッドはパラメータの勾配をゼロにクリアするために使用され、loss.backward() メソッドは勾配を計算するために使用され、optimizer.step() メソッドはパラメータを更新するために使用されます。

上記の一般的に使用される最適化アルゴリズムに加えて、torch.optim モジュールは、Adadelta、AdamW などの他の最適化アルゴリズムも提供します。ニーズに基づいてモデルをトレーニングするための適切な最適化アルゴリズムを選択できます。

Letnet5 分類 CIFAR10

#%%

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torchvision.datasets import CIFAR10
#定义LeNet5模型,模型计算过程参考:https://blog.csdn.net/liaomin416100569/article/details/130677530?spm=1001.2014.3001.5501
class LeNet5(nn.Module):
    def __init__(self):
        super(LeNet5, self).__init__()
        self.features = nn.Sequential(
            #C1 层(卷积层):6@28×28 该层使用了 6 个卷积核,每个卷积核的大小为 5×5,这样就得到了 6 个 feature map(特征图)。
            nn.Conv2d(3, 6, kernel_size=5),
            nn.ReLU(inplace=True),
            #S2 层(下采样层,也称池化层):6@14×14,池化单元为 2×2,因此,6 个特征图的大小经池化后即变为 14×14
            nn.MaxPool2d(kernel_size=2, stride=2),
            #C3 层(卷积层):16@10×10  C3 层有 16 个卷积核,卷积模板大小为 5×5 C3 层的特征图大小为(14-5+1)×(14-5+1)= 10×10。
            nn.Conv2d(6, 16, kernel_size=5),
            nn.ReLU(inplace=True),
            #S4(下采样层,也称池化层):16@5×5,与 S2 的分析类似,池化单元大小为 2×2,因此,该层与 C3 一样共有 16 个特征图,每个特征图的大小为 5×5。
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.classifier = nn.Sequential(
            #LeNet-5模型中的C5层是一个全连接层。在LeNet-5模型中,前两个卷积层(C1和C3)之后是一个池化层(S2和S4),
            # 然后是一个全连接层(C5),最后是输出层(F6)。全连接层C5的输入是S4层的输出,它将这个输入展平为一个向量,
            # 并将其连接到输出层F6。因此,C5层是一个全连接层,而不是卷积层,这里和文中有些冲突。
            #C5 层(卷积层):120 该层有 120 个卷积核,每个卷积核的大小仍为 5×5,因此有 120 个特征图,特征图大小为(5-5+1)×(5-5+1)= 1×1。这样该层就刚好变成了全连接
            nn.Linear(16 * 5 * 5, 120),
            nn.ReLU(inplace=True),
            #F6 层(全连接层):84,该层有 84 个特征图,特征图大小与 C5 一样都是 1×1
            nn.Linear(120, 84),
            nn.ReLU(inplace=True),
            # OUTPUT 层(输出层):10
            nn.Linear(84, 10)
        )

    def forward(self, x):
        x = self.features(x)
        #张量x在第0个维度上的大小,因为第0个维度是数据批次数(行数),s4层后的维度是(批次数,16,5,5)
        #转换成2维就是(行数,16*5*5),-1表示自动计算合并成最后一个维度
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x
model = LeNet5()
"""
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])是一种数据预处理操作,用于对图像数据进行归一化处理。这个操作会将每个像素的数值减去均值(mean)并除以标准差(std)。
在这个例子中,mean=[0.5, 0.5, 0.5]表示将每个通道的像素值减去0.5,std=[0.5, 0.5, 0.5]表示将每个通道的像素值除以0.5。这样处理后,图像的像素值会在-1到1之间。
归一化可以帮助提高模型的训练效果和稳定性,因为它可以使输入数据的分布更加接近标准正态分布。此外,对于不同的数据集,可能需要不同的均值和标准差进行归一化操作,以使数据的分布更加合理。
在使用PyTorch的transforms.Normalize时,通常需要将其与其他数据预处理操作一起使用,例如transforms.ToTensor()将图像转换为张量。可以通过transforms.Compose将多个预处理操作组合在一起,形成一个数据预处理管道。
"""
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
#下载训练集,data是数据数组,target是标签
train_dataset = CIFAR10(root='./data', train=True, download=True, transform=transform)
#下载测试集
test_dataset = CIFAR10(root='./data', train=False, download=True, transform=transform)
#数据批处理和打乱,一次64条数据
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
#使用交叉熵损失函数
criterion = nn.CrossEntropyLoss()
#使用随机梯度下降法优化参数,梯度下降的学习率是0.001
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
#判断是否有gpu如果有的话讲模型附加到cuda设备上
#momentum参数通过累积之前的梯度信息,使得参数更新具有一定的惯性,从而在参数空间中更快地找到全局最优解或局部最优解。
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
#模型对数据集进行10次epoch
num_epochs = 10
for epoch in range(num_epochs):
    model.train()
    epoch_loss = 0.0
    
    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)
        
        optimizer.zero_grad()
        
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()
    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss/len(train_loader):.4f}")
"""
model.eval()是PyTorch中用于将模型设置为评估模式的函数。当调用model.eval()时,模型的行为会发生变化,包括:
   1. Batch Normalization和Dropout等具有随机性的层会固定住,不再产生随机变化。
   2. 模型的参数不会被更新,即不会进行梯度计算和反向传播。
   3. 在推断阶段,模型会根据输入数据生成输出,而不会进行训练。
  通常,在测试或评估模型时,需要调用model.eval()来确保模型的行为与训练时保持一致。
这样可以避免由于Batch Normalization和Dropout等层的随机性而导致结果不稳定。在调用model.train()之前,
应该使用model.eval()将模型切换回训练模式,要将模型切换回训练模式,可以使用model.train()方法。
"""   
model.eval()
correct = 0
total = 0
#torch.no_grad()是一个上下文管理器,将其包裹的代码块中的所有操作都不会计算梯度。
# 通常用于在不需要计算梯度的情况下进行推理或评估。
with torch.no_grad():
    for images, labels in test_loader:
        #数据加载到显存
        images = images.to(device)
        labels = labels.to(device)
        
        outputs = model(images)
        #获取输出数据中概率最高的那一个
        _, predicted = torch.max(outputs.data, 1)
        #总共数据行
        total += labels.size(0)
        #正确的数据行
        correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f"Test Accuracy: {accuracy:.2f}%")

RNN

nn.RNN

nn.RNNこれは、シーケンス データを処理するための PyTorch のリカレント ニューラル ネットワーク モジュールです。nn.RNN一般的に使用されるパラメータと説明は次のとおりです。

  • input_size: フィーチャの寸法を入力します。
  • hidden_size: 隠れ層のフィーチャの次元。
  • num_layers:RNNの層数。
  • nonlinearity: アクティベーション関数、デフォルトは「tanh」です。「tanh」、「relu」などを使用できます。
  • bias: オフセットを使用するかどうか。デフォルトは True です。
  • batch_first: 入力データの最初の次元がバッチ サイズであるかどうかに関係なく、デフォルトは False です。
  • dropout: 出力レイヤーにドロップアウト操作を適用するかどうか。デフォルトは 0、つまりドロップアウトは使用されません。
  • bidirectional: 双方向 RNN を使用するかどうか。デフォルトは False です。

これらのパラメータはnn.RNN作成時に設定できます。例えば:

import torch.nn as nn

input_size = 10
hidden_size = 20
num_layers = 2

rnn = nn.RNN(input_size, hidden_size, num_layers)

これにより、入力特徴次元が 10、隠れ層特徴次元が 20 の 2 層 RNN モデルが作成されます。

受信データ形式

nn.RNN入力データ形式は通常 3 次元テンソルであり、具体的な形式は次のとおりです。

  • (デフォルト)の場合batch_first=False、入力データの形状は です(sequence_length, batch_size, input_size)
  • の場合batch_first=True、入力データの形状は です(batch_size, sequence_length, input_size)

で、

  • sequence_lengthシーケンスの長さ、つまりタイムステップ数を表します。
  • batch_size各バッチのサンプル数を示します。
  • input_size入力フィーチャの寸法を表します。

たとえば、3 つのサンプルを含むバッチがあり、各サンプルのシーケンス長が 4、入力特徴の次元が 5 であると仮定すると、入力データの形状は または になり(4, 3, 5)ます(3, 4, 5)

torch.randn()関数を使用して、テスト用のランダムな入力データを生成できます。次に例を示します。

import torch.nn as nn

batch_size = 3
sequence_length = 4
input_size = 5

input_data = torch.randn(sequence_length, batch_size, input_size)
rnn = nn.RNN(input_size, hidden_size, num_layers)
output, hidden = rnn(input_data)

このうち、outputは RNN の各タイム ステップの出力であり、hidden最後のタイム ステップの隠れた状態です。

場合

"""
PyTorch中实现了如今最常用的三种RNN:RNN(vanilla RNN)、LSTM和GRU。此外还有对应的三种RNNCell。
RNN和RNNCell层的区别在于前者能够处理整个序列,而后者一次只处理序列中一个时间点的数据,
前者封装更完备更易于使用,后者更具灵活性。RNN层可以通过组合调用RNNCell来实现。
理论参考:https://blog.csdn.net/liaomin416100569/article/details/131380370?spm=1001.2014.3001.5501
输入参数和RNN参数解释参考readme.md
"""
import torch as t
import torch.nn as nn
#注意默认(时间步,批次数,数据维度)
sequence_length =3
batch_size =2
input_size =4
input=t.randn(sequence_length,batch_size,input_size)
print("输入数据",input)
rnnModel=nn.RNN(input_size,3,1)
#其中,output是RNN每个时间步的输出,hidden是最后一个时间步的隐藏状态。
output, hidden=rnnModel(input)
print("RNN最后时间步隐藏层",hidden)
print("RNN最后时间步隐藏层维度",hidden.shape)
print("RNN所有隐藏层",output)
print("RNN所有隐藏层维度",output.shape)

出力:


输入数据 tensor([[[ 0.5364, -0.5291,  0.3117, -0.0282],
         [-0.2012,  0.9933,  1.5328, -0.8234]],

        [[ 1.3270, -1.2367,  0.5925,  1.0894],
         [-1.8035,  0.3598, -0.4404,  0.4921]],

        [[-0.6487, -0.0487, -0.9728,  0.7563],
         [ 1.2929,  0.5146,  1.2296,  1.0124]]])
RNN最后时间步隐藏层 tensor([[[0.2800, 0.8572, 0.3759],
         [0.5901, 0.4742, 0.9417]]], grad_fn=<StackBackward>)
RNN最后时间步隐藏层维度 torch.Size([1, 2, 3])
RNN所有隐藏层 tensor([[[ 0.5862,  0.7417,  0.8068],
         [ 0.9564,  0.5668,  0.6112]],

        [[-0.1729,  0.7310,  0.9879],
         [ 0.6202,  0.7824,  0.3075]],

        [[ 0.2800,  0.8572,  0.3759],
         [ 0.5901,  0.4742,  0.9417]]], grad_fn=<StackBackward>)
RNN所有隐藏层维度 torch.Size([3, 2, 3])

nn.LSTM

nn.LSTMこれは PyTorch のリカレント ニューラル ネットワーク モジュールであり、Long Short-Term Memory (LSTM) アーキテクチャに基づいています。LSTM は特別なタイプのリカレント ニューラル ネットワークで、ゲート メカニズムを使用して従来のリカレント ニューラル ネットワークにおける勾配の消失および爆発の問題を解決することで、長期の依存関係をより適切に処理できます。

nn.LSTM主なパラメータには次のものがあります。

  • input_size: 入力データの特徴次元。
  • hidden_size: 隠れ層の次元は、LSTM ユニットによって出力される次元でもあります。
  • num_layers: LSTM のレイヤー数。デフォルトは 1 です。
  • bias: オフセットを使用するかどうか。デフォルトは True です。
  • batch_first: 入力データの次元順序が (バッチ、シーケンス、フィーチャ) のいずれであっても、デフォルトは False です。
  • dropout: 過学習を防ぐためにドロップアウトを適用するかどうか。デフォルトは 0 で、ドロップアウトが使用されないことを意味します。
  • bidirectional: 双方向 LSTM を使用するかどうか。デフォルトは False です。

nn.LSTM入力データ形式は通常 3 次元テンソルであり、特定の形式はbatch_firstパラメータ設定によって異なります。False (デフォルト値)の場合batch_first、入力データの次元は (seq_len、batch、input_size) である必要があります。ここで、seq_len はシーケンスの長さを表し、batch はバッチのサイズを表し、input_size は入力データの特徴次元を表します。 。Trueの場合batch_first、入力データの次元は (batch、seq_len、input_size) である必要があります。

nn.LSTM順伝播プロセスは、入力データのタイム ステップと層の数に従って反復計算し、最後のタイム ステップの出力と、最後のタイム ステップの隠れ状態とメモリ セルの状態を返します。これらの出力は、分類や回帰などの下流タスクに使用できます。

使用するとnn.LSTM、さまざまなタスクやデータに合わせてパラメーターを調整できます。nn.LSTMCellさらに、カスタム LSTM ネットワークは、を使用して構築できます。

nn.LSTM戻り値は、output と (hidden_​​state, cell_state) の 2 つの要素を含むタプルです。

  1. 出力: LSTM モデルの隠れ状態出力を表します。これは、各タイム ステップでのモデルの出力を含むタプルです。具体的には、出力の形式は(seq_len, batch, num_directions * hidden_size)次のようになります。

    • seq_len入力シーケンスの長さを表します。
    • batch入力データのバッチ サイズを表します。
    • num_directionsLSTM モデルの方向の数を示します。通常は 1 または 2 (双方向 LSTM)。
    • hidden_size非表示の状態を表す次元。
  2. (hidden_​​state, cell_state): LSTM モデルの最後のタイム ステップの隠れ状態とセルの状態を表します。それらの形状は次のとおりです(num_layers * num_directions, batch, hidden_size)

    • num_layersLSTM モデルの層の数を示します。
    • num_directionsLSTM モデルの方向の数を示します。通常は 1 または 2 (双方向 LSTM)。
    • batch入力データのバッチ サイズを表します。
    • hidden_size非表示の状態を表す次元。

これら 2 つの戻り値は、シーケンス アノテーション、言語モデリング、その他のタスクなど、さらなる処理と分析に使用できます。
つまり、hidden_​​state は出力の最後の値であり、タイム ステップごとに cell_state の
ケースが存在します。

lstmModel=nn.LSTM(input_size,3,1)
#其中,output是RNN每个时间步的输出,hidden是最后一个时间步的隐藏状态。
output, (h, c) =lstmModel(input)
print("LSTM隐藏层输出的维度",output.shape)
print("LSTM隐藏层最后一个时间步输出的维度",h.shape)
print("LSTM隐藏层最后一个时间步细胞状态",c.shape)

出力

LSTM隐藏层输出的维度 torch.Size([3, 2, 3])
LSTM隐藏层最后一个时间步输出的维度 torch.Size([1, 2, 3])
LSTM隐藏层最后一个时间步细胞状态 torch.Size([1, 2, 3])

nn.GRU

nn.GRUこれは、PyTorch のリカレント ニューラル ネットワーク (RNN) モジュールであり、ゲート付きリカレント ユニット (GRU) の機能を実装します。GRU はシーケンス データの処理に使用される RNN のバリアントであり、従来のリカレント ニューラル ネットワークよりも強力なモデリング機能を備えています。

GRU は、アップデート ゲートとリセット ゲートという 2 つのゲート メカニズムを導入することにより、情報の流れを制御します。これらのゲート メカニズムにより、GRU は長期的な依存関係を学習し、長いシーケンスを処理するときにシーケンス内の重要な情報をより適切に取得できるようになります。

モジュールではnn.GRU、パラメータを設定することで、GRU の入力次元、隠れ状態次元、層数などを定義できます。一般的に使用されるパラメーターの一部を次に示しますnn.GRU

  • input_size: フィーチャの寸法を入力します。
  • hidden_size: 隠れた状態の次元。
  • num_layers:GRU 層の数。
  • bias: オフセットを使用するかどうか。
  • batch_first: True の場合、入力データの形状は (batch_size、sequence_length、input_size) である必要があり、False の場合、入力データの形状は (sequence_length、batch_size、input_size) である必要があります。
  • dropout: ドロップアウト率。入力データのランダムなドロップアウト率を制御するために使用されます。
  • bidirectional: 双方向 GRU を使用するかどうか。

上記のパラメーターに加えて、順伝播計算のメソッド、モデル パラメーターをリセットするメソッドnn.GRUなど、他のいくつかのメソッドと関数も提供されます。場合forwardreset_parameters

# gru没有细胞状态
gruModel=nn.GRU(input_size,3,1)
#其中,output是RNN每个时间步的输出,hidden是最后一个时间步的隐藏状态。
output, h =gruModel(input)
print("GRU隐藏层输出的维度",output.shape)
print("GRU隐藏层最后一个时间步输出的维度",h.shape)

出力

GRU隐藏层输出的维度 torch.Size([3, 2, 3])
GRU隐藏层最后一个时间步输出的维度 torch.Size([1, 2, 3])

モデル

チェックポイント

深層学習では、チェックポイントはトレーニング中にモデルのパラメーターを保存するファイルです。これらはトレーニング サイクルごとまたは特定の時間間隔で保存されるため、トレーニング中に問題が発生した場合でもトレーニングを再開できます。チェックポイントを保存すると、トレーニングを最初から開始することなく、トレーニング中にいつでも停止および再開できます。

「.pt」は、PyTorch でモデル パラメーターを保存するために使用されるファイル拡張子です。モデルをトレーニングするとき、後で別の場所で使用したり、他のモデルにロードしたりできるように、モデルのパラメーターを .pt ファイルに保存できます。これらのファイルには、モデルがトレーニング中に学習した重みやバイアスなどのパラメーターが含まれています。PyTorch では、torch.save() 関数を使用してモデル パラメーターを .pt ファイルとして保存し、torch.load() 関数を使用してパラメーターを .pt ファイルにロードできます。

import torch
import torch.nn as nn
#模型的保存和加载
model=nn.Linear(3,1)
#修改权重和偏置后保存模型
new_weight = torch.tensor([[1.0, 2.0, 3.0]])
new_bias = torch.tensor([4.0])
model.weight = nn.Parameter(new_weight)
model.bias = nn.Parameter(new_bias)
torch.save(model.state_dict(),"./model.pt")

newModel=nn.Linear(3,1)
print("默认参数",newModel.weight,newModel.bias)
newModel.load_state_dict(torch.load("./model.pt"))
print("加载后",newModel.weight,newModel.bias)

出力

默认参数 Parameter containing:
tensor([[-0.4357, -0.0781,  0.0136]], requires_grad=True) Parameter containing:
tensor([-0.2013], requires_grad=True)
加载后 Parameter containing:
tensor([[1., 2., 3.]], requires_grad=True) Parameter containing:
tensor([4.], requires_grad=True)

内蔵モデル

PyTorchtorchvision.modelsモジュールでは、次のような、適切に実装されたクラシック ニューラル ネットワーク モデルがいくつか提供されています。

  1. アレックスネット
  2. VGG
  3. レスネット
  4. スクイーズネット
  5. 高密度ネット
  6. インセプション
  7. GoogLeNet
  8. モバイルネット
  9. シャッフルネット
  10. レスネクスト
  11. ワイド解像度ネット
  12. MNASネット

これらのモデルは、torchvision.modelsモジュールの関数を通じてインスタンス化して、独自のプロジェクトで使用できます。各モデルには事前にトレーニングされた重みがあり、カスタム データセットで微調整することもできます。ニーズに応じて適切なモデルをお選びいただけます。

以下では、models.resnet18 を使用して datasets.CIFAR10 を分類しています。

#%%

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models

# 定义数据预处理
transform = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# 加载CIFAR-10数据集
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)

# 定义模型
#参数pretrained表示是否加载预训练的权重。如果pretrained为True,那么模型将加载在ImageNet数据集上预训练的权重。
# 这些预训练的权重可以提供更好的初始权重,有助于模型在其他任务上进行迁移学习。如果pretrained为False,
# 则使用随机初始化的权重进行训练。
model = models.resnet18(pretrained=False)
num_classes = 10
model.fc = nn.Linear(512, num_classes)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 训练模型
batch_size = 64
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)

num_epochs = 10
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(num_epochs):
    model.train()
    epoch_loss = 0.0
    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)
        
        # 前向传播和计算损失
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()
    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss/len(train_loader):.4f}")
# 在测试集上评估模型
model.eval()
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)
        
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
    
    accuracy = 100 * correct / total
    print(f'Epoch [{epoch+1}/{num_epochs}], Test Accuracy: {accuracy}%')
torch.cuda.empty_cache()

トーチハブ

torch.hubこれは、事前トレーニングされたモデルをロードするための PyTorch のツールです。トレーニングされたモデルをインターネットから簡単に取得し、コードにロードして使用するためのシンプルなインターフェイスを提供します。これを使用するとtorch.hub、画像分類、オブジェクト検出、セマンティック セグメンテーションなどのさまざまな事前学習済みモデルを簡単に使用できます。

torch.hub使い方は非常に簡単で、モデルの名前空間とモデル名を指定するだけで、事前トレーニングされたモデルが自動的にダウンロードされてロードされます。たとえば、「pytorch/vision」という名前のモデルをロードするには、次のコードを使用します。

import torch model = torch.hub.load('pytorch/vision', 'resnet50', pretrained=True)

上記のコードは、「resnet50」という名前の事前トレーニング済みモデルをダウンロードしてロードし、model変数に保存します。model変数は、推論、特徴抽出などに使用できます。

torch.hubローカル モデル キャッシュもサポートされています。つまり、同じコードを複数回実行すると、モデルが再ダウンロードされるのではなく、ローカル キャッシュから自動的にロードされます。これにより、コードの効率が向上します。

全体として、torch.hubこれはさまざまな事前トレーニング済みモデルを簡単に使用してコードに統合できる非常に便利なツールであり、ディープ ラーニング プロジェクトの開発を加速します。
公式ウェブサイトのモデル検索アドレス: https://pytorch.org/hub/research-models
以下は最も人気のある 6 モデルです
ここに画像の説明を挿入します

yolov5 ターゲット検出

実際の戦闘で yolov5 ターゲット検出を使用するには、公式モデルのドキュメントを参照してください: https://pytorch.org/hub/ultralytics_yolov5/
Python>=3.8 PyTorch>=1.7 に
Ultralytics をインストールしてください。

pip install -U ultralytics

プログラミング

#%%

import torch
# Model,加载模型中的参数
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
# Images
imgs = ['https://ultralytics.com/images/zidane.jpg']  # batch of images
# Inference
results = model(imgs)
# Results
results.print()
results.save()  # or .show()
results.xyxy[0]  # img1 predictions (tensor)

runs/detect/exp/zidane.jpg が現在の実行ディレクトリに生成されます。
ここに画像の説明を挿入します

アニメーション画像を生成する

Github プロジェクトのアドレス: https://github.com/bryandlee/animegan2-pytorch
はキャラクター画像をアニメーション効果に変換できます。

from PIL import Image
import torch
from matplotlib import pyplot
model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator",pretrained="celeba_distill").eval()
face2paint = torch.hub.load("bryandlee/animegan2-pytorch:main", "face2paint", size=512)
image=Image.open("./images/lyf.png")
out = face2paint(model, image)
pyplot.imshow(out)
pyplot.show()


ここに画像の説明を挿入します
変換後の元画像
ここに画像の説明を挿入します

視覚的なモニタリング

TensorFlow では、最も一般的に使用される可視化ツールは Tensorboard ですが、TensorboardX ツールを使用すると、PyTorch でも Tensorboard の便利な機能を利用できるようになります。
pytorch1.8 以降、tensorboardx ツールは torch.utils.tensorboard パッケージに含まれています。
FaceBook は、PyTorch 用のインタラクティブな視覚化ツールである Visdom も開発しました。これは、リアルタイム データの豊富な視覚化を提供し、実験プロセスをリアルタイムで監視するのに役立ちます。

テンソルボード

Tensorboard は TensorFlow の追加ツールであり、学習プロセス中にモデルのパラメータ、評価指標、画像などを記録するために使用され、Web ページを通じて詳細とプロセスを参照して表示する機能を提供します。実験に役立つブラウザ視覚化の形式で、ニューラル ネットワークの学習プロセスを随時観察し、学習傾向を把握します。Tensorboard ツールが非常に便利なため、TensorFlow 以外の他の深層学習フレームワークも Tensorboard の便利な機能を取得したいと考え、TensorboardX が登場しました。
まず Tensorboard をインストールします

pip install tensorboard

ここの tensorboard で必要な setuptools のバージョンは低く、使用中にエラーが報告されます。

AttributeError: module 'distutils' has no attribute 'version'

バージョンをダウングレードするだけです

pip uninstall setuptools
micromamba install setuptools==59.5.0
或者用pip install setuptools==59.5.0

ツールの使用仕様
1. SummaryWriter のインスタンスを作成します。

from torch.utils.tensorboard import SummaryWriter
# 创建一个SummaryWriter的实例
writer = SummaryWriter(log_dir=None)

log_dir はログを保存するパスを表し、デフォルトでは「runs/現在の時刻_ホスト名」フォルダーに保存されます。

追加スカラー

2. add_scalar メソッド: このメソッドは、数値定数 (損失関数値など) を記録するために使用されます。その定義は次のとおりです。

add_scalar(tag, scalar_value, global_step=None, walltime=None)
  • タグ: 監視するデータの名前を示す文字列型で、任意にカスタマイズできます。名前が異なるデータは異なる曲線を使用して表示されます。
  • scalar_value: 浮動小数点型。監視および保存する値を示します。
  • global_step:横軸としてトレーニング ステップの数を示す整数
  • Walltime: 録音が行われた時刻を示す浮動小数点タイプ。デフォルトは time.time() です。
    一般に、add_scalar メソッドは、トレーニング プロセス中の損失、精度、学習率などの値の変化を記録するために使用され、トレーニング プロセスを直感的に監視できます。インジケーターを監視するたびに、add_scalar メソッドを使用する必要があります。(x 個のインジケーターを表示したい場合は、add_scalar メソッドを x 回使用します)
    3. add_image メソッドは、単一の画像データを記録するために使用されます (Pillow ライブラリのサポートが必要です)。その定義は次のとおりです。
add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')
  • tag、global_step、walltime の意味は add_scalar メソッドと同じです。
  • img_tensor: 画像データを表す PyTorch の Tensor 型または NumPy の配列型。
  • dataformats: 画像データの形式を示す文字列タイプ。デフォルトは「CHW」、つまりチャンネル x 高さ x 幅です。「CHW」、「HWC」、または「HW」などにすることもできます。
    これは線形回帰の例で、x としてエポック数、y 値として損失を使用したスカラー グラフを示しています。
#%%
import os
import shutil
def delete_directory_contents(directory):
    for filename in os.listdir(directory):  # 遍历目录下的所有文件和子目录
        file_path = os.path.join(directory, filename)  # 构建文件或子目录的完整路径
        if os.path.isfile(file_path):  # 如果是文件,则直接删除
            os.remove(file_path)
        elif os.path.isdir(file_path):  # 如果是子目录,则递归调用删除子目录中的内容
            shutil.rmtree(file_path)
#删除runs目录下的所有文件和目录            
delete_directory_contents("./runs/")            
import torch as t
import matplotlib.pyplot as plot
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter
#########例子演示梯度下降损失(每个epoch的损失)
#其中的 log_dir 表示保存日志的路径,默认会保存在“runs/ 当前时间 _ 主机名”文件夹中。
writer=SummaryWriter(log_dir=None)
t.manual_seed(42)
# 使用自动梯度实现线性回归
x=t.randn(100,1)
x_test=t.randn(20,1)
y=3*x+2+t.randn(100,1) #实际值上加上一些随机噪点
y_test=3*x+2+t.randn(100,1)

class LinearModel(nn.Module):
    def __init__(self):
        nn.Module.__init__(self)
        self.w=nn.Parameter(t.randn(1,1))
        self.b=nn.Parameter(t.randn(1))
    def forward(self,x):
        return t.mm(x,self.w)+self.b
model=LinearModel()
lossf=nn.MSELoss()
#定义优化器,第一个参数为模型的参数,参数传入后,自动获取他的梯度并且-梯度*学习率
optim=t.optim.SGD(model.parameters(),lr=0.01)
#训练100次,100次梯度下降,计算到最小损失时的w和b
epochCount=100
for epoch in range(epochCount):
    y_pre=model(x)
    #注意梯度清零,否则会累加
    optim.zero_grad()  
    loss=lossf(y_pre,y)
    writer.add_scalar("Loss/train",loss,epoch)
    loss.backward()
    #更新参数w和b
    optim.step()
     
plot.plot(x,y,'.')
plot.plot(x.data.numpy(),y_pre.data.numpy())
plot.show()
writer.close()

実行後、runs ディレクトリにログが生成されるので、tensorboard がインストールされている環境に切り替えて、tensorboard --logdir=runs コマンドを実行します。

Tensorboard はホットロードされており、エポック数の調整や再実行など、上記のコードはリアルタイムで更新されます。

(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模块>tensorboard --logdir=runs
TensorFlow installation not found - running with reduced feature set.
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.13.0 at http://localhost:6006/ (Press CTRL+C to quit)

アクセス: http://localhost:6006/
ここに画像の説明を挿入します
エポックが約 80 に達すると、基本的な損失が非常に小さいことがわかります。
コードの epochCount を 20 に調整する
ここに画像の説明を挿入します
と、損失勾配が滑らかなレベルに達していないことがわかります。近似グラフを見てみましょ
ここに画像の説明を挿入します
う epochCount を 10000 に調整する
ここに画像の説明を挿入します
と、基本的に 100 付近で横ばいになり、その後のトレーニングが冗長になるため、エポックを 100 にすることが最も適切であることがわかります。

ヒストグラムの追加

このメソッドを使用してadd_histogram、一連のデータのヒストグラムを記録します。

add_histogram(tag, values, global_step=None, bins='tensorflow', walltime=None, max_bins=None)

パラメータ

  • タグ(文字列): データ名
  • (torch.Tensor、numpy.array、または string/blobname): ヒストグラムの構築に使用されるデータ
  • global_step (int、オプション): トレーニング ステップ
  • bins (文字列、オプション): 値には、「tensorflow」、「auto」、「fd」などが含まれます。このパラメータはバケット化方法を決定します。詳細については、ここを参照してください
  • Walltime (float、オプション): レコードが発生した時刻。デフォルトは次のとおりです。time.time()
  • max_bins (int、オプション): バケットの最大数
    データ、トレーニング パラメーター、および特徴のヒストグラムを観察して、それらのおおよその分布を理解し、ニューラル ネットワークのトレーニング プロセスを支援できます。
    1000個のデータを平均0、分散1で10回生成したとして、各回の変動を観察してみましょう。
import numpy as np
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter()
flag = 1
if flag :
    for x in range(10):
        data_1 = np.arange(1000)
        data_2 = np.random.normal(size=1000)
        #直方图的结构是y轴是第多少次,x轴显示value的波动
        writer.add_histogram("data1",data_1,x)
        writer.add_histogram('data2',data_2,x)
writer.close()

ここに画像の説明を挿入します
右側の座標はサイクル数を表し、下の座標はこれら 1,000 個の数値の分布を表します。

走行グラフ(グラフ)

このメソッドを使用してadd_graphニューラル ネットワークを視覚化します。

add_graph(model, input_to_model=None, verbose=False, **kwargs)

パラメータ

  • モデル (torch.nn.Module): 可視化するネットワーク モデル
  • input_to_model (torch.Tensor または torch.Tensor のリスト、オプション): ニューラル ネットワークに入力される変数または変数のセット
    add_scalar 線形回帰のコードで、線形モデル入力 x の計算グラフを出力します。
model=LinearModel()
#加入代码
writer.add_graph(model,model.w)

ここに画像の説明を挿入します

画像追加_画像

add_image単一の画像データを記録する方法を使用します。このメソッドにはpillowライブラリのサポートが必要であることに注意してください。

add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')

パラメータ

  • タグ(文字列): データ名
  • img_tensor (torch.Tensor / numpy.array): 画像データ
  • global_step (int、オプション): トレーニング ステップ
  • Walltime (float、オプション): レコードが発生した時刻。デフォルトは次のとおりです。time.time()
  • dataformats (文字列、オプション): 画像データの形式。デフォルトは です。'CHW'つまりまたはなどChannel x Height x Widthにすることもできます。'CHW''HWC''HW'

add_image通常、生成モデルの生成効果をリアルタイムで観察したり、モデルのデバッグに役立てるためにセグメンテーションとターゲット検出の結果を視覚化するために使用します。

知恵

フォローアップ

おすすめ

転載: blog.csdn.net/liaomin416100569/article/details/131576169