質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

Chainerで簡単なCNNを実装したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,627

kanpan

score 20

chainerを使って、簡単なCNNを実装したいのですが、見たことがない形式のエラーが出てうまく実行できません。どうすればよいのでしょうか?

ソースコード

CNNSC.py

#encoding: utf8

from chainer import ChainList
import chainer.functions as F
import chainer.links as L

"""
Code for Convolutional Neural Networks for Sentence Classification

author: ichiroex
"""

# リンク数を可変にしたいのでChainListを使用する
class CNNSC(ChainList):
    def __init__(self,
                 input_channel,
                 output_channel,
                 filter_height,
                 filter_width,
                 n_label,
                 max_sentence_len):
        # フィルター数、使用されたフィルター高さ、最大文長は後から使う
        self.cnv_num = len(filter_height)
        self.filter_height = filter_height
        self.max_sentence_len = max_sentence_len

        # Convolution層用のLinkをフィルター毎に追加
        # Convolution2D( 入力チャンネル数, 出力チャンネル数(形毎のフィルターの数), フィルターの形(タプル形式で), パディングサイズ )
        link_list = [L.Convolution2D(input_channel, output_channel, (i, filter_width), pad=0) for i in filter_height]
        # Dropoff用のLinkを追加
        link_list += [L.Linear(output_channel * self.cnv_num, output_channel * self.cnv_num)]
        # 出力層へのLinkを追加
        link_list += [L.Linear(output_channel * self.cnv_num, n_label)]

        # ここまで定義したLinkのリストを用いてクラスを初期化する
        super(CNNSC, self).__init__(*link_list)

        # ちなみに
        # self.add_link(link)
        # みたいにリンクを列挙して順々に追加していってもOKです

    def __call__(self, x, train=True):
        # フィルタを通した中間層を準備
        h_conv = [None for _ in self.filter_height]
        h_pool = [None for _ in self.filter_height]

        # フィルタ形毎にループを回す
        for i, filter_size in enumerate(self.filter_height):
            # Convolition層を通す
            h_conv[i] = F.relu(self[i](x))
            # Pooling層を通す
            h_pool[i] = F.max_pooling_2d(h_conv[i], (self.max_sentence_len+1-filter_size))
        # Convolution+Poolingを行った結果を結合する
        concat = F.concat(h_pool, axis=2)
        # 結合した結果に対してDropoutをかける
        h_l1 = F.dropout(F.tanh(self[self.cnv_num+0](concat)), ratio=0.5, train=train)
        # Dropoutの結果を出力層まで圧縮する
        y = self[self.cnv_num+1](h_l1)

        return y

if __name__ == '__main__':
    model = L.Classifier(CNNSC(input_channel=1,
                           output_channel=100,
                           filter_height=[3,4,5],
                           filter_width=20,
                           n_label=2,
                           max_sentence_len=20))
    print('done process')

実行プログラム

import numpy as np
import sys, os
import six
import argparse
import chainer
import chainer.links as L
from chainer import optimizers, cuda, serializers
import chainer.functions as F

from CNNSC import CNNSC

def get_parser():

    DEF_GPU = -1
    DEF_DATA = "..{sep}Data{sep}input.dat".format(sep=os.sep)
    DEF_EPOCH = 100
    DEF_BATCHSIZE = 50

    #引数の設定
    parser = argparse.ArgumentParser()
    parser.add_argument('data',
                        type=str,
                        default=DEF_DATA,
                        metavar='PATH',
                        help='an input data file')
    parser.add_argument('--gpu',
                        dest='gpu',
                        type=int,
                        default=DEF_GPU,
                        metavar='CORE_NUMBER',
                        help='use CORE_NUMBER gpu (default: use cpu)')
    parser.add_argument('--epoch',
                        dest='epoch',
                        type=int,
                        default=DEF_EPOCH,
                        help='number of epochs to learn')
    parser.add_argument('--batchsize',
                        dest='batchsize',
                        type=int,
                        default=DEF_BATCHSIZE,
                        help='learning minibatch size')
    parser.add_argument('--save-model',
                        dest='save_model',
                        action='store',
                        type=str,
                        default=None,
                        metavar='PATH',
                        help='save model to PATH')
    parser.add_argument('--save-optimizer',
                        dest='save_optimizer',
                        action='store',
                        type=str,
                        default=None,
                        metavar='PATH',
                        help='save optimizer to PATH')
    parser.add_argument('--baseline',
                        dest='baseline',
                        action='store_true',
                        help='if true, run baseline model')

    return parser

def save_model(model, file_path='sc_cnn.model'):
    # modelを保存
    print ('save the model')
    model.to_cpu()
    serializers.save_npz(file_path, model)

def save_optimizer(optimizer, file_path='sc_cnn.state'):
    # optimizerを保存
    print ('save the optimizer')
    serializers.save_npz(file_path, optimizer)

def train(args):

    batchsize   = args.batchsize    # minibatch size
    n_epoch     = args.epoch        # エポック数

    hight = 100
    width = 200

    #訓練データの読み込み
    x_train = np.load('posneg_train_data.npy')
    y_train = np.load('posneg_train_label.npy')

    #テストデータの読み込み
    x_test = np.load('posneg_test_data.npy')
    y_test = np.load('posneg_test_label.npy')

    N_test = y_test.size         # test data size
    N = len(x_train)             # train data size
    in_units = x_train.shape[1]  # 入力層のユニット数 (語彙数)

    # (nsample, channel, height, width) の4次元テンソルに変換
    input_channel = 1
    x_train = x_train.reshape(len(x_train), input_channel, height, width)
    x_test  = x_test.reshape(len(x_test), input_channel, height, width)

    n_label = 2 # ラベル数
    filter_height = [3,4,5] # フィルタの高さ
    baseline_filter_height = [3]
    filter_width  = width # フィルタの幅 (embeddingの次元数)
    output_channel = 100
    decay = 0.0001 # 重み減衰
    grad_clip = 3  # gradient norm threshold to clip
    max_sentence_len = height # max length of sentences

    # モデルの定義
    if args.baseline == False:
        # 提案モデル
        model = CNNSC(input_channel,
                      output_channel,
                      filter_height,
                      filter_width,
                      n_label,
                      max_sentence_len)
    else:
        # ベースラインモデル (フィルタの種類が1つ)
        model = CNNSC(input_channel,
                      output_channel,
                      baseline_filter_height,
                      filter_width,
                      n_label,
                      max_sentence_len)

    # Setup optimizer
    optimizer = optimizers.AdaDelta()
    optimizer.setup(model)
    optimizer.add_hook(chainer.optimizer.GradientClipping(grad_clip))
    optimizer.add_hook(chainer.optimizer.WeightDecay(decay))

    #GPUを使うかどうか
    if args.gpu >= 0:
        cuda.check_cuda_available()
        cuda.get_device(args.gpu).use()
        model.to_gpu()
    xp = np if args.gpu < 0 else cuda.cupy #args.gpu <= 0: use cpu, otherwise: use gpu

    # Learning loop
    for epoch in six.moves.range(1, n_epoch + 1):

        print ('epoch', epoch, '/', n_epoch)

        # training
        perm = np.random.permutation(N) #ランダムな整数列リストを取得
        sum_train_loss     = 0.0
        sum_train_accuracy = 0.0
        for i in six.moves.range(0, N, batchsize):

            #perm を使い x_train, y_trainからデータセットを選択 (毎回対象となるデータは異なる)
            x = chainer.Variable(xp.asarray(x_train[perm[i:i + batchsize]])) #source
            t = chainer.Variable(xp.asarray(y_train[perm[i:i + batchsize]])) #target

            model.zerograds()

            y = model(x)
            loss = F.softmax_cross_entropy(y, t) # 損失の計算
            accuracy = F.accuracy(y, t) # 正解率の計算

            sum_train_loss += loss.data * len(t)
            sum_train_accuracy += accuracy.data * len(t)

            # 最適化を実行
            loss.backward()
            optimizer.update()

        print('train mean loss={}, accuracy={}'.format(sum_train_loss / N, sum_train_accuracy / N)) #平均誤差

        # evaluation
        sum_test_loss     = 0.0
        sum_test_accuracy = 0.0
        for i in six.moves.range(0, N_test, batchsize):

            # all test data
            x = chainer.Variable(xp.asarray(x_test[i:i + batchsize]))
            t = chainer.Variable(xp.asarray(y_test[i:i + batchsize]))

            y = model(x, False)
            loss = F.softmax_cross_entropy(y, t) # 損失の計算
            accuracy = F.accuracy(y, t) # 正解率の計算

            sum_test_loss += loss.data * len(t)
            sum_test_accuracy += accuracy.data * len(t)

        print(' test mean loss={}, accuracy={}'.format(sum_test_loss / N_test, sum_test_accuracy / N_test)) #平均誤差

        sys.stdout.flush()

    return model, optimizer

def main():
    parser = get_parser()
    args = parser.parse_args()
    model, optimizer = train(args)

    if args.save_model != None:
        save_model(model)
    if args.save_optimizer != None:
        save_optimizer(optimizer)

if __name__ == "__main__":
    main()

エラーメッセージ

(base) C:\jikken>python confirm.py
usage: confirm.py [-h] [--gpu CORE_NUMBER] [--epoch EPOCH]
                  [--batchsize BATCHSIZE] [--save-model PATH]
                  [--save-optimizer PATH] [--baseline]
                  PATH
confirm.py: error: the following arguments are required: PATH

備考

参考にしたページはこちらです。
https://qiita.com/ichiroex/items/7ff1cff3840520cf2410

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • tiitoi

    2018/11/28 15:57 編集

    confirm.py に argparse で自分で位置引数 PATH を設定したのに、実行時に渡さないで実行しているからだと思います。

    キャンセル

  • kanpan

    2018/11/28 16:13

    ありがとうございました。

    キャンセル

回答 1

check解決した方法

0

argparserをわたした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る