0

私はPytorch githubで見つけたコードハットをデータに合わせて修正しましたが、損失の結果は大きく、繰り返しごとに大きくなり、後でnan.Codeは私に与えませんどんなエラーでも、損失の結果でも予測もありません。 私は単純な線形回帰を扱う別のコードを持っており、すべて正常に動作します。私はここに簡単なものがないと思うが、私はそれを見ることができない。どんな助けもありがとう。PytorchとPolynomial線形回帰問題

コード:

import sklearn.linear_model as lm 
from sklearn.preprocessing import PolynomialFeatures 
import torch 
import torch.autograd 
import torch.nn.functional as F 
from torch.autograd import Variable 


train_data = torch.Tensor([ 
    [40, 6, 4], 
    [44, 10, 4], 
    [46, 12, 5], 
    [48, 14, 7], 
    [52, 16, 9], 
    [58, 18, 12], 
    [60, 22, 14], 
    [68, 24, 20], 
    [74, 26, 21], 
    [80, 32, 24]]) 
test_data = torch.Tensor([ 
    [6, 4], 
    [10, 5], 
    [4, 8]]) 

x_train = train_data[:,1:3] 
y_train = train_data[:,0] 

POLY_DEGREE = 3 
input_size = 2 
output_size = 1 

poly = PolynomialFeatures(input_size * POLY_DEGREE, include_bias=False) 
x_train_poly = poly.fit_transform(x_train.numpy()) 


class Model(torch.nn.Module): 

    def __init__(self): 
     super(Model, self).__init__() 
     self.fc = torch.nn.Linear(poly.n_output_features_, output_size) 

    def forward(self, x): 
     return self.fc(x) 

model = Model()  
criterion = torch.nn.MSELoss() 
optimizer = torch.optim.SGD(model.parameters(), lr=0.001) 

losses = [] 

for i in range(10): 
    optimizer.zero_grad() 
    outputs = model(Variable(torch.Tensor(x_train_poly))) 
    print(outputs) 
    loss = criterion(outputs, Variable(y_train)) 
    print(loss.data[0]) 
    losses.append(loss.data[0]) 
    loss.backward()  
    optimizer.step() 
    if loss.data[0] < 1e-4: 
     break  

print('n_iter', i) 
print(loss.data[0]) 
plt.plot(losses) 
plt.show() 

出力:

[393494300459008.0、INF、INF、INFは、NaN、NaNには、NaN、NaNで、ナン、ナン]

n_iter

9ナノ

答えて

0

問題の原因となるものがいくつかあります。それらの一部または全部を変更することで、合理的な結果が得られ、学習が可能になります。

  1. (多項式)フィーチャには大きなばらつきがあり、非常に大きな値をとっています。 np.max(x_train_poly)をチェックしてください。ウェイトマトリックスをランダムに初期化すると、初期予測が大幅にオフになり、損失が無限に近づくようになります。これに対処するには、まずフィーチャを標準化することができます(つまり、フィーチャごとに平均0と分散1を作成します)。非常に深いネットワークでは、同様の考え方が「バッチ標準化」と呼ばれています。あなたが興味を持っている場合、あなたはもっとここで読むことができます:https://arxiv.org/abs/1502.03167あなたはあなたの例を修正するために次の操作を行うことができますのポイントの一種である、

    means = np.mean(x_train_poly,axis=0,keepdims=True) 
    std = np.std(x_train_poly,axis=0,keepdims=True) 
    x_train_poly = (x_train_poly - means)/std 
    
  2. あなたの現在のモデルは、任意の隠れ層を持っていませんニューラルネットワークと非線形回帰/分類器を構築する。あなたが今やっていることは、27の入力フィーチャーに線形変換を適用して、出力に近いものを得ることです。複数の層を有するない点はありません、他ので、私は、最初の線形変換した後、非直線性を追加した

    hidden_dim = 50 
    
    class Model(torch.nn.Module): 
        def __init__(self): 
         super(Model, self).__init__() 
         self.layer1 = torch.nn.Linear(poly.n_output_features_, hidden_dim) 
         self.layer2 = torch.nn.Linear(hidden_dim, output_size) 
    
        def forward(self, x): 
         return self.layer2(torch.nn.ReLU()(self.layer1(x))) 
    

    注:あなたは、このような追加の層を追加することができます。

  3. 最初の予測の問題は、最初は大きく外れており、無限に近づいています。損失関数の最初の「間違い」の大きさの倍数を本質的に2倍にする二乗損失を使用しています。また、損失が無限になると、勾配の更新は基本的に無限大であるため、二乗損失を使用しているため、エスケープすることはできません。時に便利な簡単な修正は、代わりに円滑なL1損失を使用することです。本質的に、区間[0、1]上のMSEおよびその区間外のL1の損失。

    criterion = torch.nn.SmoothL1Loss() 
    
    すでに賢明な何か(もうすなわち無INFファイル)にあなたを取得
  4. が、今 は学習率をチューニングしてweight_decayの導入を検討し次のように変更します。オプティマイザを変更することもできます。

    optimizer = torch.optim.SGD(model.parameters(), lr=0.01, weight_decay=1) 
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=0.1)