pytorchを用いて三重螺旋の学習を行わせているのですが、重みが更新されているのに損失関数の値や精度が一向に向上しません。
またネットで調べてみてもどのようにすればよいのかわかりませんでした。ぜひアドバイスが欲しいです。よろしくお願いいたします。
Python
1from __future__ import print_function 2from statistics import mode 3#from math import gamma #コマンドライン引数を受け取る処理をするモジュール 4import torch # ライブラリ「PyTorch」のtorchパッケージをインポート 5import torch.nn as nn # 「ニューラルネットワーク」モジュールの別名定義 6import torch.nn.functional as F #様々な関数を持つクラス 7import torch.optim as optim#adam,SGDなどの最適化手法をもつモジュール 8from torchvision import datasets,transforms#データの前処理に必要なモジュール 9from torch.optim.lr_scheduler import StepLR#学習率の更新を行う関数 10import pandas as pd 11from sklearn.model_selection import train_test_split 12import numpy as np 13import matplotlib.pyplot as plt 14import time 15 16class Net(nn.Module): 17 def __init__(self): 18 super(Net, self).__init__() 19 input_size=torch.tensor([2]) #入力層 20 hidden_size=torch.tensor([20]) #中間層 21 output_size=torch.tensor([3]) #出力層 22 self.fc1 = nn.Linear(input_size,hidden_size) # Linearは「全結合層」を指す(入力層、出力層) 23 self.fc2 = nn.Linear(hidden_size,output_size) # Linearは「全結合層」を指す(入力層、出力層) 24 25 def forward(self, x): 26 x = self.fc1(x) 27 x = torch.sigmoid(x) 28 x = self.fc2(x) 29 output =torch.log_softmax(x, dim=1) 30 return output 31 32 #予測の精度を求める関数 33 34 def accuracy(self,x,t): 35 y = self.forward(x) 36 y=y.cpu().data.numpy() 37 y = np.argmax(y, axis=1)#axis=列方向に見ていく(横) 38 t=t.cpu().data.numpy() 39 accuracy = np.sum(y == t) / float(x.shape[0]) 40 return accuracy 41 42#データ分割 43data = pd.read_table("3class.txt", sep=" ", header=None) 44x = data[0].values 45y = data[1].values 46t = data[2].values 47 48x_train, x_test,y_train,y_test,t_train, t_test = train_test_split(x,y,t,train_size=0.9) 49 50 51train_x=np.array([]) 52for i in range(len(x_train)): 53 train_x = np.append(train_x,[ x_train[i] , y_train[i] ] ) 54 55train_x=train_x.reshape(len(x_train),2).astype(float) 56train_x = torch.FloatTensor(train_x)#Tensor型に変換 57 58test_x=np.array([]) 59for i in range(len(x_test)): 60 test_x = np.append(test_x,[ x_test[i] , y_test[i] ] ) 61 62test_x=test_x.reshape(len(x_test),2).astype(float) 63test_x = torch.FloatTensor(test_x)#Tensor型に変換 64 65t_train = torch.LongTensor(t_train)#Tensor型に変換 66t_test = torch.LongTensor(t_test)#Tensor型に変換 67 68num=int(27*1e+4) 69batch_size=100 70train_size=train_x.shape[0]#2702 71epoch=int(max(int(train_size / batch_size), 1))#27 72lr=0.1 73seed=0 74epoch_num=1 75 76use_cuda =torch.cuda.is_available()#cudaを使えと指定されcudaが使える場合にcudaを使用 77torch.manual_seed(seed)#疑似乱数を作る時に使う、元となる数字。 シード値が同じなら常に同じ乱数が作られる。(再現性がある) 78 79device = torch.device("cuda" if use_cuda else "cpu")#GPUを指定なければCPU 80device=torch.device("cpu") 81#GPUに送る 82train_x=train_x.to(device) 83train_t=t_train.to(device)#修正 84test_x=test_x.to(device) 85test_t=t_test.to(device)#修正 86 87train_loss_list = [] 88test_loss_list = [] 89train = [] 90test = [] 91epoch_num_list=[] 92 93model = Net().to(device)#netインスタンス生成。modelはレイヤーの構成親クラスを継承 94optimizer = optim.SGD(model.parameters(),lr=0.1)#最適化手法,model.parameters():自動で重みとバイアスを設定してくれる 95scheduler = StepLR(optimizer, step_size=1,gamma=0.1)#step_size:更新タイミングのエポック数,gamma:更新率 96 97#print(list(model.parameters())) 98# 開始 99start_time = time.perf_counter() 100 101# ダミー処理 102time.sleep(1) 103 104for i in range(num): 105 #バッチ処理 106 batch_mask = np.random.choice(train_size, batch_size) 107 x_batch = train_x[batch_mask] 108 t_batch = train_t[batch_mask] 109 110 model.train() 111 output = model.forward(x_batch)#推論の結果をoutputに出力 112 loss = F.nll_loss(output,t_batch)#損失関数の関数 113 optimizer.zero_grad()#保持しているデータを初期化(勾配が累積されるため) 114 loss.backward()#誤差逆伝搬法;勾配を求めている 115 optimizer.step()#重みとバイアスをoptimizerを使って更新 116 scheduler.step()#学習率の更新 117 118 if i % (epoch) == 0: 119 model.eval() 120 train_acc = model.accuracy(train_x,train_t) 121 test_acc = model.accuracy(test_x, test_t) 122 train.append(train_acc) 123 test.append(test_acc) 124 output = model.forward(train_x) 125 train_loss_list.append(F.nll_loss(output,train_t)) 126 print(i,epoch_num, train_acc, test_acc,F.nll_loss(output,train_t).item()) 127 output = model.forward(test_x) 128 test_loss_list.append(F.nll_loss(output,test_t)) 129 epoch_num_list.append(epoch_num) 130 epoch_num=epoch_num+1 131# 修了 132end_time = time.perf_counter() 133 134# 経過時間を出力(秒) 135elapsed_time = end_time - start_time 136print(elapsed_time) 137#print(list(model.parameters())) 138 139train=torch.tensor(train) 140test=torch.tensor(test) 141train_loss_list=torch.tensor(train_loss_list) 142test_loss_list=torch.tensor(test_loss_list) 143 144train =train.cpu().data.numpy() 145test = test.cpu().data.numpy() 146train_loss_list = train_loss_list.cpu().data.numpy() 147test_loss_list = test_loss_list.cpu().data.numpy() 148 149plt.ylim([0,1.2]) 150#plt.plot(epoch_num_list,train,color='b',label='train') 151#plt.plot(epoch_num_list,test ,color='r',label='test') 152plt.plot(epoch_num_list,train_loss_list,color='b',label='train') 153plt.plot(epoch_num_list,test_loss_list ,color='r',label='test') 154plt.xlabel("epoch") 155plt.ylabel("loss") 156plt.legend() 157plt.show()
実行結果(一部切り抜き)
エポック数、訓練精度、テスト精度、損失関数の値
9980 0.33641746854182086 0.30564784053156147 1.1340349912643433
9981 0.33641746854182086 0.30564784053156147 1.1340349912643433
9982 0.33641746854182086 0.30564784053156147 1.1340349912643433
9983 0.33641746854182086 0.30564784053156147 1.1340349912643433
9984 0.33641746854182086 0.30564784053156147 1.1340349912643433
9985 0.33641746854182086 0.30564784053156147 1.1340349912643433
9986 0.33641746854182086 0.30564784053156147 1.1340349912643433
9987 0.33641746854182086 0.30564784053156147 1.1340349912643433
9988 0.33641746854182086 0.30564784053156147 1.1340349912643433
9989 0.33641746854182086 0.30564784053156147 1.1340349912643433
9990 0.33641746854182086 0.30564784053156147 1.1340349912643433
9991 0.33641746854182086 0.30564784053156147 1.1340349912643433
9992 0.33641746854182086 0.30564784053156147 1.1340349912643433
9993 0.33641746854182086 0.30564784053156147 1.1340349912643433
9994 0.33641746854182086 0.30564784053156147 1.1340349912643433
9995 0.33641746854182086 0.30564784053156147 1.1340349912643433
9996 0.33641746854182086 0.30564784053156147 1.1340349912643433
9997 0.33641746854182086 0.30564784053156147 1.1340349912643433
9998 0.33641746854182086 0.30564784053156147 1.1340349912643433
9999 0.33641746854182086 0.30564784053156147 1.1340349912643433
10000 0.33641746854182086 0.30564784053156147 1.1340349912643433
追加
Python
1train_x=np.array([]) 2for i in range(len(x_train)): 3 train_x = np.append(train_x,[ x_train[i] , y_train[i] ] ) 4 5train_x=train_x.reshape(len(x_train),2).astype(float) 6train_x = torch.tensor(train_x,dtype=float,requires_grad=True)#Tensor型に変換,微分可能にする 7train_x=train_x.to(torch.float) 8 9test_x=np.array([]) 10for i in range(len(x_test)): 11 test_x = np.append(test_x,[ x_test[i] , y_test[i] ] ) 12 13test_x=test_x.reshape(len(x_test),2).astype(float) 14test_x = torch.tensor(test_x,dtype=float,requires_grad=True)#Tensor型に変換,微分可能にする 15test_x=test_x.to(torch.float)
回答1件