PyTorchコード作成に伴う問題と解決策
PyTorchコード作成で発生した問題
エラーメッセージ:no module named xxx
xxxはカスタムフォルダの名前です。
検索できないので、現在のパスをカバンの検索ディレクトリに追加します。
解決方法:
Linuxシステムの下でimg.shapeがAttributeErrを間違えました:“NoneType”object hasのatribute‘shpe’
img=cv 2.imread()で、1枚の画像を読み取る場合、img.sharpeは3つの量を含むタプルで、それぞれ:
img.shop[0]:画像の高さ
img.shop[1]:画像の幅
img.shop[2]:画像のチャンネル数
ファイルの読み込みエラーまたはファイルのパスが正しいかどうかを確認します。
エラーメッセージ:TypeError:slice indices must be integers or None or have an index method
cropped_im=img[ny 1:ny 2,nx 1:nx 2,:
解決方法:ny 1:ny 2、nx 1:nx 2をintタイプに変換する必要があります。
エラーメッセージ:Input type(touch.cuda.Double Tensor)and weight type(toch.cudia.Float Tensor)shuld be the same
以下の3つのセグメントはそれぞれData type CPU tensor GPU tenssorです。
32-bit floating point touch.Float Tensor toch.cudia.Float Tensor
64 bit floating point touch.Double Tensor toch.cude.Double Tensor
エラーがタイプに変換されました。
np.floatをnp.float 32に変更しました。
バージョン問題旧式の書き方
tenssor([0.1,0.2])
エラーメッセージ:Type Error:'float'oject is not subscriptable
下付きa=x.tolist()[0]が追加されました。
下付きa=x.tolist()を削除します。
エラーメッセージ:argment‘input’(position 1)must be Tensor,not list
リストをテナントに変換する必要があります。
aをリストと仮定する
元のGPUモデルが保存されていると仮定して、CPUモデルに変換します。
元のコード
元のコード
RuntimeError:Attempting to deserialze Object on CUDA device 1 but touch.cdva.device_count()is 1.Please use touch.load with map_location to map your storages to an existing device.
またはRuntimeError:expected device cuda:0 but got device cuda:1
エラーの原因の一つ
CUDA 1グラフィックカードを使って保存を訓練したモデルファイルは、CUDA 0を使って検証します。
コードに書いてあります
ライセConnection Error(e,request=request)
requests.exceptions.Connection Errror:HTTPConnection Pool(host='localhost',port=8097):Max retries exceedwith url:/udate(Caused by NewConnection ror(')):Max rection 3.HTTPnection offect 11
Exception in user code:
ソリューション
visdomの可視化プログラムが起動されていませんので、すべてのエラーが発生しました。
端末でコマンドvisdomを実行すると次のような情報が見られます。
モデルに対してもデータに対しても、キューダ()はCPUからGPUへのメモリ移行が可能ですが、効果は違います。
Model:
Tensor:
PyTorch 0.4の累積損失計算の違い
広く使われているモードでtotal_loss+=loss.data[0]を例にします。Python 0.4.0の前に、lossはボリュームのVarableをカプセル化しましたが、Python 0.4.0のlossは現在ゼロ次元のスカラです。スカラをインデックスするのは意味がないです。loss.item()を使用して、スカラーからPython数字を取得することができます。したがって、
適応CPUとGPU機器のtrick
公式説明:Returns a new Tensor、detached from the current graph、The reult will never require gradient
モデルAとモデルBがあると仮定して、Bの入力としてAの出力を必要としますが、訓練の時はモデルBだけを訓練します。
pytouchにおけるloss関数のパラメータ設定
Cross EntropyLossを例にとって:
Cross EntropyLoss(self,weight=None,size_average=None、ignore_index=-100,reduce=None,reduction='element wise_mean
reduce=Falseなら、sizuaverageパラメータが無効になり、ベクトル形式のloss、すなわちbatchの各要素に対応するlossを直接返します。
reduce=Trueの場合、lossはスカラーを返します。
size_ならaverage=Trueは、loss.meanに戻ります。
size_ならaverage=Falseは、loss.sumに戻ります。
weight:1 Dの重みベクトルを入力し、各カテゴリのloss重み付けを行います。次の式で示します。
イグノア.index:無視する目標値を選択し、入力勾配に貢献しないようにします。size_ならaverage=Trueは、無視されないターゲットのlossの平均を計算します。
reduction:オプションのパラメータは、「none」「element wise」です。mean'124'sum'はパラメータの文字どおりです。
多GPUの処理メカニズム
マルチGPUを使う場合は、PyTorchの処理ロジックを覚えておくべきです。
各GPU上でモデルを初期化する。
前方伝播時に、batchを各GPUに割り当てて計算します。
得られた出力を主GPU上で集計し,lossを計算し,逆伝搬し,主GPU上の重みを更新した。
メインGPU上のモデルを他のGPUにコピーします。
トレーニング中に損失が発生しました。
モデルを訓練する時、nanに損失が発生した場合
勾配がnaに現れる3つの理由があります。
勾配爆発つまり勾配値が範囲を超えてnanになります。小学校の習度を調整したり、BN層をプラスしたり、勾配カットをしたりして解決があるかどうか試してみます。
損失関数またはネットワーク設計。例えば、0を除いて、またはいくつかの境界の状況が現れて、例えばロゴ(0)、sqrt(0)などの関数が導けなくなります。
汚いデータです。事前に入力データを判断して、naがあるかどうか確認してください。
naデータの判断方法を追加します。
注意しますnanやinfのような数値は==またはisでは判断できません。安全のために、統一的にmath.isnanまたはnumpy.isnanを使いましょう。
toch.as_tensor:dataのためにtensorを生成します。
dataがすでにtenssorであり、dtypeとdeviceがパラメータと同じであれば、生成されたtensorはdataとメモリを共有する。dataがdarrayであり、dtypeが対応している場合、devicesはcpuである場合、メモリを共有するのと同じである。他の場合はメモリを共有しません。
エラーメッセージ:no module named xxx
xxxはカスタムフォルダの名前です。
検索できないので、現在のパスをカバンの検索ディレクトリに追加します。
解決方法:
import sys
sys.path.append('..') #
sys.path.append('/home/xxx') #
import os
sys.path.append(os.getcwd()) # #
現在の端末のコマンドライン設定も可能です。
export PYTHONPATH=$PYTHONPATH:./
エラーメッセージ:AttributeError:‘NoneType’object hasのatribute‘shop’height,width,chanel=img.shapeLinuxシステムの下でimg.shapeがAttributeErrを間違えました:“NoneType”object hasのatribute‘shpe’
img=cv 2.imread()で、1枚の画像を読み取る場合、img.sharpeは3つの量を含むタプルで、それぞれ:
img.shop[0]:画像の高さ
img.shop[1]:画像の幅
img.shop[2]:画像のチャンネル数
ファイルの読み込みエラーまたはファイルのパスが正しいかどうかを確認します。
エラーメッセージ:TypeError:slice indices must be integers or None or have an index method
cropped_im=img[ny 1:ny 2,nx 1:nx 2,:
解決方法:ny 1:ny 2、nx 1:nx 2をintタイプに変換する必要があります。
エラーメッセージ:Input type(touch.cuda.Double Tensor)and weight type(toch.cudia.Float Tensor)shuld be the same
以下の3つのセグメントはそれぞれData type CPU tensor GPU tenssorです。
32-bit floating point touch.Float Tensor toch.cudia.Float Tensor
64 bit floating point touch.Double Tensor toch.cude.Double Tensor
エラーがタイプに変換されました。
np.floatをnp.float 32に変更しました。
import torchvision.transforms as transforms
import numpy as np
transform = transforms.ToTensor()
def convert_image_to_tensor(image):
"""convert an image to pytorch tensor
image: numpy array , h * w * c
image_tensor: pytorch.FloatTensor, c * h * w
"""
image = image.astype(np.float32)
return transform(image)
エラーメッセージ:RuntimeError:ゼロ・ディメンティナ(at position 0)cannot be contentatedバージョン問題旧式の書き方
import torch
x = torch.tensor(0.1)
y = torch.tensor(0.2)
z = torch.cat((x, y))
新式の書き方に直す
x = torch.tensor([0.1])
y = torch.tensor([0.2])
z = torch.cat((x, y))
print(z)
結果tenssor([0.1,0.2])
エラーメッセージ:Type Error:'float'oject is not subscriptable
下付きa=x.tolist()[0]が追加されました。
下付きa=x.tolist()を削除します。
エラーメッセージ:argment‘input’(position 1)must be Tensor,not list
リストをテナントに変換する必要があります。
aをリストと仮定する
torch.tensor(a)
GPUモデルとCPUモデルの切り替え元のGPUモデルが保存されていると仮定して、CPUモデルに変換します。
torch.save(model, os.path.join( "./complete.pth"))
cpu_model = torch.load("./complete.pth", map_location=lambda storage, loc: storage)
dummy_input = torch.randn(1, 3, 224, 224)
元のCPUモデルが保存されていると仮定して、GPUモデルに変換します。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
torch.save(model, os.path.join( "./complete.pth"))
gpu_model = torch.load("./complete.pth", map_location=lambda storage, loc: storage.cuda)
dummy_input = torch.randn(1, 3, 224, 224)
dummy_input = dummy_input.to(device)
エラーメッセージRuntimeError:Subtraction、the-operator、with a boot tens is not supported.If you are trying to invert a mark、use the~or logcalnot()operator instead.元のコード
# Store only unsuppressed boxes for this class
image_boxes.append(class_decoded_locs[1 - suppress])
image_labels.append(torch.LongTensor((1 - suppress).sum().item() * [c]).to(device))
image_scores.append(class_scores[1 - suppress])
に変更
image_boxes.append(class_decoded_locs[~suppress])
image_labels.append(torch.LongTensor((~ suppress).sum().item() * [c]).to(device))
image_scores.append(class_scores[~suppress])
エラーメッセージRuntimeError:Expected object of scalar type Bype got scalar type Bool for argment腩2‘other’in call to_同前max元のコード
suppress = torch.zeros((n_above_min_score), dtype=torch.uint8).to(device)
に変更
suppress = torch.zeros((n_above_min_score), dtype=torch.bool).to(device)
UserWarning:volatile was removed and now hasのeffect.Use with touch.no_grad():instead.
#
...
x = Variable(torch.randn(1), volatile=True)
return x
#
with torch.no_grad():
...
x = torch.randn(1)
return x
エラーメッセージRuntimeError:Attempting to deserialze Object on CUDA device 1 but touch.cdva.device_count()is 1.Please use touch.load with map_location to map your storages to an existing device.
またはRuntimeError:expected device cuda:0 but got device cuda:1
エラーの原因の一つ
CUDA 1グラフィックカードを使って保存を訓練したモデルファイルは、CUDA 0を使って検証します。
コードに書いてあります
device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)
コマンドラインの設定でどのGPUが表示されますか?
export CUDA_VISIBLE_DEVICES=1 #GPU
export CUDA_VISIBLE_DEVICES=0,1,2,3#4
コードから変更することもできます。
checkpoint = torch.load(checkpoint,map_location=‘cuda:0')
エラーメッセージライセConnection Error(e,request=request)
requests.exceptions.Connection Errror:HTTPConnection Pool(host='localhost',port=8097):Max retries exceedwith url:/udate(Caused by NewConnection ror(')):Max rection 3.HTTPnection offect 11
Exception in user code:
ソリューション
visdomの可視化プログラムが起動されていませんので、すべてのエラーが発生しました。
端末でコマンドvisdomを実行すると次のような情報が見られます。
Checking for scripts.
It's Alive!
INFO:root:Application Started
You can navigate to http://localhost:8097
nn.Module.cda()とTensor.cda()モデルに対してもデータに対しても、キューダ()はCPUからGPUへのメモリ移行が可能ですが、効果は違います。
Model:
model = model.cuda()
model.cuda()
上の2つは同じ効果を達成することができます。すなわち、model自身のメモリ移動です。Tensor:
model = Model()
tensor = torch.zeros([2, 3, 10, 10])
model.cuda()
tensor.cuda()
tensor_cuda = tensor.cuda()
model(tensor) #
model(tensor_cuda) #
nn.Moduleとは違って、tenssor.cudiaを呼び出して、GPUメモリ上のこのtenssorオブジェクトのコピーを返すだけで、自分自身を変更することはありません。そのためにテナントを再賦課しなければならない、すなわちテナント=テナンタ.PyTorch 0.4の累積損失計算の違い
広く使われているモードでtotal_loss+=loss.data[0]を例にします。Python 0.4.0の前に、lossはボリュームのVarableをカプセル化しましたが、Python 0.4.0のlossは現在ゼロ次元のスカラです。スカラをインデックスするのは意味がないです。loss.item()を使用して、スカラーからPython数字を取得することができます。したがって、
total_loss = total_loss + loss.item()
累積損失時にPython数字に変換しないと、プログラムメモリの使用量が増加する場合があります。これは、上の表式の右側はもともとPython浮動小数点であり、現在はゼロ次元テンソルであるからです。したがって、総損失はテンソルとそれらの勾配履歴を積算し、これは大きなautgrad図を発生し、メモリと計算リソースを消費することができる。適応CPUとGPU機器のtrick
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Model().to(device)
total_loss = 0
for input, target in train_loader:
input, target = input.to(device), target.to(device)
...
total_loss = total_loss + loss.item()
with torch.no_grad():
for input, target in test_loader:
...
toch.Tensor.detachの使用公式説明:Returns a new Tensor、detached from the current graph、The reult will never require gradient
モデルAとモデルBがあると仮定して、Bの入力としてAの出力を必要としますが、訓練の時はモデルBだけを訓練します。
input_B = output_A.detach
二つの計算図の勾配伝達を切断して、私たちが必要とする機能を実現することができます。pytouchにおけるloss関数のパラメータ設定
Cross EntropyLossを例にとって:
Cross EntropyLoss(self,weight=None,size_average=None、ignore_index=-100,reduce=None,reduction='element wise_mean
reduce=Falseなら、sizuaverageパラメータが無効になり、ベクトル形式のloss、すなわちbatchの各要素に対応するlossを直接返します。
reduce=Trueの場合、lossはスカラーを返します。
size_ならaverage=Trueは、loss.meanに戻ります。
size_ならaverage=Falseは、loss.sumに戻ります。
weight:1 Dの重みベクトルを入力し、各カテゴリのloss重み付けを行います。次の式で示します。
イグノア.index:無視する目標値を選択し、入力勾配に貢献しないようにします。size_ならaverage=Trueは、無視されないターゲットのlossの平均を計算します。
reduction:オプションのパラメータは、「none」「element wise」です。mean'124'sum'はパラメータの文字どおりです。
多GPUの処理メカニズム
マルチGPUを使う場合は、PyTorchの処理ロジックを覚えておくべきです。
各GPU上でモデルを初期化する。
前方伝播時に、batchを各GPUに割り当てて計算します。
得られた出力を主GPU上で集計し,lossを計算し,逆伝搬し,主GPU上の重みを更新した。
メインGPU上のモデルを他のGPUにコピーします。
トレーニング中に損失が発生しました。
モデルを訓練する時、nanに損失が発生した場合
勾配がnaに現れる3つの理由があります。
勾配爆発つまり勾配値が範囲を超えてnanになります。小学校の習度を調整したり、BN層をプラスしたり、勾配カットをしたりして解決があるかどうか試してみます。
損失関数またはネットワーク設計。例えば、0を除いて、またはいくつかの境界の状況が現れて、例えばロゴ(0)、sqrt(0)などの関数が導けなくなります。
汚いデータです。事前に入力データを判断して、naがあるかどうか確認してください。
naデータの判断方法を追加します。
注意しますnanやinfのような数値は==またはisでは判断できません。安全のために、統一的にmath.isnanまたはnumpy.isnanを使いましょう。
import numpy as np
if np.any(np.isnan(input.cpu().numpy())):
print("Input data has NaN!")
if(np.isnan(loss.item())):
print("Loss value is NaN!")
pytochメモリ漏れtoch.as_tensor:dataのためにtensorを生成します。
dataがすでにtenssorであり、dtypeとdeviceがパラメータと同じであれば、生成されたtensorはdataとメモリを共有する。dataがdarrayであり、dtypeが対応している場合、devicesはcpuである場合、メモリを共有するのと同じである。他の場合はメモリを共有しません。
import torch
import numpy
a = numpy.array([1, 2, 3])
t = torch.as_tensor(a)
以上は個人の経験ですので、参考にしていただければと思います。