dev_str = 'cuda:{0}'.format( args.gpu) if torch.cuda.is_available() and args.gpu >= 0 else 'cpu' dev = torch.device(dev_str) # オプション情報の設定・表示 epochs = max(1, args.epochs) # 総エポック数(繰り返し回数) batchsize = max(1, args.batchsize) # バッチサイズ model_filepath = args.model # 学習結果のモデルの保存先ファイル print('device: {0}'.format(dev_str), file=sys.stderr) print('epochs: {0}'.format(epochs), file=sys.stderr) print('batchsize: {0}'.format(batchsize), file=sys.stderr) print('model file: {0}'.format(model_filepath), file=sys.stderr) print('', file=sys.stderr) # 学習データの読み込み labels, imgfiles, labeldict, labelnames = read_image_list( IMAGE_LIST, DATA_DIR) # ネットワークモデルの作成(本来のVGGFace2顔画像を縦横半分にしたものを入力画像として用いるので,WIDTH と HEIGHT を 2 で割る) cnn = myUpSamplingAE(WIDTH // 2, HEIGHT // 2, CHANNELS) ### ここから下は,必要に応じて書き換えると良い ### # 追加条件の指定 conditions = {} conditions['in_channels'] = CHANNELS # 入力画像のチャンネル数が 3(カラー画像) conditions['out_channels'] = CHANNELS # 出力画像のチャンネル数も 3(カラー画像) conditions['input_scale'] = 0.5 # 本来のVGGFace2顔画像を縦横半分に(0.5倍)して入力画像とする # 学習処理 cnn = train( device=dev, # 使用するGPUのID,変えなくて良い
def run(): # オプション情報の設定・表示 epochs = max(1, args.epochs) # 総エポック数(繰り返し回数) batchsize = max(1, args.batchsize) # バッチサイズ model_filepath = args.model # 学習結果のモデルの保存先ファイル # print('device: {0}'.format(dev_str), file=sys.stderr) # print('epochs: {0}'.format(epochs), file=sys.stderr) # print('batchsize: {0}'.format(batchsize), file=sys.stderr) # print('model file: {0}'.format(model_filepath), file=sys.stderr) # print('', file=sys.stderr) # 画像の縦幅・横幅・チャンネル数の設定 width = 240 # MNIST文字画像の場合,横幅は 28 pixels height = 240 # MNIST文字画像の場合,縦幅も 28 pixels channels = 3 # MNIST文字画像はグレースケール画像なので,チャンネル数は 1 color_mode = 0 if channels == 1 else 1 # 学習データの読み込み labels, imgfiles, labeldict, labelnames = read_image_list( IMAGE_LIST, data_dir=DATA_DIR) n_samples = len(imgfiles) # 学習データの総数 n_classes = len(labeldict) # クラス数 with open(MODEL_DIR + 'labeldict.pickle', 'wb') as f: pickle.dump(labeldict, f) # ラベル名からラベル番号を与える辞書をファイルに保存 with open(MODEL_DIR + 'labelnames.pickle', 'wb') as f: pickle.dump(labelnames, f) # ラベル番号からラベル名を与える配列をファイルに保存 # 評価用データの読み込み labels_ev, imgfiles_ev, labeldict, dmy = read_image_list( IMAGE_LIST_EV, data_dir=DATA_DIR, dic=labeldict) n_samples_ev = len(imgfiles_ev) # 評価用データの総数 # 画像認識器の作成 model = myCNN(width, height, channels, n_classes) model = model.to(dev) # 損失関数の定義 loss_func = nn.CrossEntropyLoss() # softmax cross entropy # オプティマイザーの用意 optimizer = optim.Adam(model.parameters()) # 最もaccuracyが高かったepochとそのaccuracy best_epoch = 0 best_accuracy = 0.0 # 学習処理ループ for e in range(epochs): # 現在のエポック番号を表示 # print('Epoch {0}'.format(e + 1), file=sys.stderr) # 損失関数の値が小さくなるように識別器のパラメータを更新 model.train() n_input = 0 sum_loss = 0 perm = np.random.permutation(n_samples) batch_range = min(batchsize, n_samples % batchsize) for i in range(0, n_samples, batchsize * 10): # 高速化のため,ミニバッチ10個につき1個しか学習に用いないことにする model.zero_grad() x = torch.tensor(load_images( imgfiles, ids=perm[i: i + batch_range], mode=color_mode), device=dev) # 学習データを読み込む t = torch.tensor(labels[perm[i: i + batch_range]], device=dev, dtype=torch.long) loss = loss_func(model(x), t) loss.backward() optimizer.step() sum_loss += float(loss) * len(x) n_input += len(x) del loss del t del x # 損失関数の現在値を表示 # print(' train loss = {0:.4f}'.format(sum_loss / n_input), file=sys.stderr) # 評価用データに対する識別精度を計算・表示 model.eval() n_failed = 0 for i in range(0, n_samples_ev, batchsize): x = torch.tensor(load_images(imgfiles_ev, ids=np.arange(i, min( n_samples_ev, i + batchsize)), mode=color_mode), device=dev) # 評価用データを読み込む t = torch.tensor(labels_ev[i: i + batchsize], device=dev, dtype=torch.long) y = model.classify(x) y_cpu = y.to('cpu').detach().numpy().copy() t_cpu = t.to('cpu').detach().numpy().copy() n_failed += np.count_nonzero(np.argmax(y_cpu, axis=1) - t_cpu) del y_cpu del t_cpu del y del x del t acc = (n_samples_ev - n_failed) / n_samples_ev if best_accuracy < acc: best_epoch = e best_accuracy = acc # print(' accuracy = {0:.2f}%'.format(100 * acc), file=sys.stderr) # 現在のモデルをファイルに自動保存 # torch.save(model.to('cpu').state_dict(), MODEL_DIR + # 'model_ep{0}.pth'.format(e + 1)) model = model.to(dev) # print('', file=sys.stderr) # 最終結果のモデルをファイルに保存 # torch.save(model.to('cpu').state_dict(), model_filepath) return (best_epoch, best_accuracy)
# オプション情報の設定・表示 epochs = max(1, args.epochs) # 総エポック数(繰り返し回数) batchsize = max(1, args.batchsize) # バッチサイズ model_filepath = args.model # 学習結果のモデルの保存先ファイル print('device: {0}'.format(dev_str), file=sys.stderr) print('epochs: {0}'.format(epochs), file=sys.stderr) print('batchsize: {0}'.format(batchsize), file=sys.stderr) print('model file: {0}'.format(model_filepath), file=sys.stderr) print('', file=sys.stderr) # 画像の縦幅・横幅・チャンネル数の設定 width = 128 # VGGFace2顔画像の場合,横幅は 128 pixels height = 128 # VGGFace2顔画像の場合,縦幅も 128 pixels # 学習データの読み込み labels, imgfiles, labeldict, labelnames = read_image_list( IMAGE_LIST, DATA_DIR) n_samples = len(imgfiles) # 学習データの総数 # 評価用データの読み込み labels_ev, imgfiles_ev, labeldict, dmy = read_image_list(IMAGE_LIST_EV, DATA_DIR, dic=labeldict) n_samples_ev = len(imgfiles_ev) # 評価用データの総数 # カラー化オートエンコーダの作成 model = myColorizationAE(width, height) model = model.to(dev) # 損失関数の定義 loss_func = nn.MSELoss() # mean squared error
with open(MODEL_DIR + 'labelnames.pickle', 'rb') as f: labelnames = pickle.load(f) n_classes = len(labelnames) # 学習済みの画像認識器をロード model = myCNN(width, height, channels, n_classes) model.load_state_dict(torch.load(model_filepath)) model = model.to(dev) model.eval() # 入力画像に対し認識処理を実行 if in_filepath == '': ### ファイル名を指定せずに実行した場合・・・全評価用データに対する識別精度を表示 ### labels_ev, imgfiles_ev, labeldict, dmy = read_image_list(IMAGE_LIST_EV, DATA_DIR, dic=labeldict) # 評価用データの読み込み n_samples_ev = len(imgfiles_ev) # 評価用データの総数 n_failed = 0 # row: expected, col: actual eval_matrix = [[0 for j in range(7)] for i in range(7)] for i in range(0, n_samples_ev, batchsize): offset = min(n_samples_ev, i + batchsize) x = torch.tensor(load_images(imgfiles_ev, ids=np.arange(i, offset), mode=color_mode), device=dev) t = labels_ev[i : i + batchsize] y = model.classify(x) y_cpu = y.to('cpu').detach().numpy().copy() recognized = np.argmax(y_cpu, 1) for j in range(len(t)): eval_matrix[t[j]][recognized[j]] += 1 n_failed += np.count_nonzero(np.argmax(y_cpu, axis=1) - t) del y_cpu