pytorchを用いて三重螺旋の学習を行わせているのですが、重みが更新されているのに損失関数の値や精度が一向に向上しません。
またネットで調べてみてもどのようにすればよいのかわかりませんでした。ぜひアドバイスが欲しいです。よろしくお願いいたします。
Python
from __future__ import print_function from statistics import mode #from math import gamma #コマンドライン引数を受け取る処理をするモジュール import torch # ライブラリ「PyTorch」のtorchパッケージをインポート import torch.nn as nn # 「ニューラルネットワーク」モジュールの別名定義 import torch.nn.functional as F #様々な関数を持つクラス import torch.optim as optim#adam,SGDなどの最適化手法をもつモジュール from torchvision import datasets,transforms#データの前処理に必要なモジュール from torch.optim.lr_scheduler import StepLR#学習率の更新を行う関数 import pandas as pd from sklearn.model_selection import train_test_split import numpy as np import matplotlib.pyplot as plt import time class Net(nn.Module): def __init__(self): super(Net, self).__init__() input_size=torch.tensor([2]) #入力層 hidden_size=torch.tensor([20]) #中間層 output_size=torch.tensor([3]) #出力層 self.fc1 = nn.Linear(input_size,hidden_size) # Linearは「全結合層」を指す(入力層、出力層) self.fc2 = nn.Linear(hidden_size,output_size) # Linearは「全結合層」を指す(入力層、出力層) def forward(self, x): x = self.fc1(x) x = torch.sigmoid(x) x = self.fc2(x) output =torch.log_softmax(x, dim=1) return output #予測の精度を求める関数 def accuracy(self,x,t): y = self.forward(x) y=y.cpu().data.numpy() y = np.argmax(y, axis=1)#axis=列方向に見ていく(横) t=t.cpu().data.numpy() accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy #データ分割 data = pd.read_table("3class.txt", sep=" ", header=None) x = data[0].values y = data[1].values t = data[2].values x_train, x_test,y_train,y_test,t_train, t_test = train_test_split(x,y,t,train_size=0.9) train_x=np.array([]) for i in range(len(x_train)): train_x = np.append(train_x,[ x_train[i] , y_train[i] ] ) train_x=train_x.reshape(len(x_train),2).astype(float) train_x = torch.FloatTensor(train_x)#Tensor型に変換 test_x=np.array([]) for i in range(len(x_test)): test_x = np.append(test_x,[ x_test[i] , y_test[i] ] ) test_x=test_x.reshape(len(x_test),2).astype(float) test_x = torch.FloatTensor(test_x)#Tensor型に変換 t_train = torch.LongTensor(t_train)#Tensor型に変換 t_test = torch.LongTensor(t_test)#Tensor型に変換 num=int(27*1e+4) batch_size=100 train_size=train_x.shape[0]#2702 epoch=int(max(int(train_size / batch_size), 1))#27 lr=0.1 seed=0 epoch_num=1 use_cuda =torch.cuda.is_available()#cudaを使えと指定されcudaが使える場合にcudaを使用 torch.manual_seed(seed)#疑似乱数を作る時に使う、元となる数字。 シード値が同じなら常に同じ乱数が作られる。(再現性がある) device = torch.device("cuda" if use_cuda else "cpu")#GPUを指定なければCPU device=torch.device("cpu") #GPUに送る train_x=train_x.to(device) train_t=t_train.to(device)#修正 test_x=test_x.to(device) test_t=t_test.to(device)#修正 train_loss_list = [] test_loss_list = [] train = [] test = [] epoch_num_list=[] model = Net().to(device)#netインスタンス生成。modelはレイヤーの構成親クラスを継承 optimizer = optim.SGD(model.parameters(),lr=0.1)#最適化手法,model.parameters():自動で重みとバイアスを設定してくれる scheduler = StepLR(optimizer, step_size=1,gamma=0.1)#step_size:更新タイミングのエポック数,gamma:更新率 #print(list(model.parameters())) # 開始 start_time = time.perf_counter() # ダミー処理 time.sleep(1) for i in range(num): #バッチ処理 batch_mask = np.random.choice(train_size, batch_size) x_batch = train_x[batch_mask] t_batch = train_t[batch_mask] model.train() output = model.forward(x_batch)#推論の結果をoutputに出力 loss = F.nll_loss(output,t_batch)#損失関数の関数 optimizer.zero_grad()#保持しているデータを初期化(勾配が累積されるため) loss.backward()#誤差逆伝搬法;勾配を求めている optimizer.step()#重みとバイアスをoptimizerを使って更新 scheduler.step()#学習率の更新 if i % (epoch) == 0: model.eval() train_acc = model.accuracy(train_x,train_t) test_acc = model.accuracy(test_x, test_t) train.append(train_acc) test.append(test_acc) output = model.forward(train_x) train_loss_list.append(F.nll_loss(output,train_t)) print(i,epoch_num, train_acc, test_acc,F.nll_loss(output,train_t).item()) output = model.forward(test_x) test_loss_list.append(F.nll_loss(output,test_t)) epoch_num_list.append(epoch_num) epoch_num=epoch_num+1 # 修了 end_time = time.perf_counter() # 経過時間を出力(秒) elapsed_time = end_time - start_time print(elapsed_time) #print(list(model.parameters())) train=torch.tensor(train) test=torch.tensor(test) train_loss_list=torch.tensor(train_loss_list) test_loss_list=torch.tensor(test_loss_list) train =train.cpu().data.numpy() test = test.cpu().data.numpy() train_loss_list = train_loss_list.cpu().data.numpy() test_loss_list = test_loss_list.cpu().data.numpy() plt.ylim([0,1.2]) #plt.plot(epoch_num_list,train,color='b',label='train') #plt.plot(epoch_num_list,test ,color='r',label='test') plt.plot(epoch_num_list,train_loss_list,color='b',label='train') plt.plot(epoch_num_list,test_loss_list ,color='r',label='test') plt.xlabel("epoch") plt.ylabel("loss") plt.legend() plt.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
train_x=np.array([]) for i in range(len(x_train)): train_x = np.append(train_x,[ x_train[i] , y_train[i] ] ) train_x=train_x.reshape(len(x_train),2).astype(float) train_x = torch.tensor(train_x,dtype=float,requires_grad=True)#Tensor型に変換,微分可能にする train_x=train_x.to(torch.float) test_x=np.array([]) for i in range(len(x_test)): test_x = np.append(test_x,[ x_test[i] , y_test[i] ] ) test_x=test_x.reshape(len(x_test),2).astype(float) test_x = torch.tensor(test_x,dtype=float,requires_grad=True)#Tensor型に変換,微分可能にする test_x=test_x.to(torch.float)
まだ回答がついていません
会員登録して回答してみよう