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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3324閲覧

tensorflow インスタンス変数の初期化は可能?

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2017/06/25 17:36

編集2017/08/28 07:53

オブジェクト指向の練習を兼ねて、CNNをクラスで実装したいと考えています。

python

1import tensorflow as tf 2import numpy as np 3from dataset.mnist import load_mnist 4 5(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True) 6 7class 畳み込み層: 8 def __init__(self, f枚数1, f枚数2): 9 self.フィルター1 = tf.Variable(tf.truncated_normal([5,5,1,f枚数1], 10 stddev=0.1)) 11 self.バイアス1 = tf.Variable(tf.constant(0.1, shape=[f枚数1])) 12 13 self.フィルター2 = tf.Variable(tf.truncated_normal([5,5,f枚数1, f枚数2], 14 stddev=0.1)) 15 self.バイアス2 = tf.Variable(tf.constant(0.1, shape=[f枚数2])) 16 17 def 伝達処理(self, 入力値): 18 """引数の入力値には、tf.placeholderの4次元配列を渡す""" 19 20 f1, b1 = self.フィルター1, self.バイアス1 21 f2, b2 = self.フィルター2, self.バイアス2 22 23 コンバート1 = tf.nn.conv2d(入力値, f1, strides=[1,1,1,1], 24 padding="SAME") 25 活性化1 = tf.nn.relu(コンバート1 + b1) 26 27 プーリング1 = tf.nn.max_pool(活性化1, ksize=[1,2,2,1], 28 strides=[1,2,2,1], padding="SAME") 29 30 コンバート2 = tf.nn.conv2d(プーリング1, f2, strides=[1,1,1,1], 31 padding="SAME") 32 活性化2 = tf.nn.relu(コンバート2 + b2) 33 プーリング2 = tf.nn.max_pool(活性化2, ksize=[1,2,2,1], 34 strides=[1,2,2,1], padding="SAME") 35 36 return プーリング2 37 38class 全結合層(畳み込み層): 39 def __init__(self, 入力数, 中間数, 出力数): 40 41 self.重み1 = tf.Variable(tf.truncated_normal \ 42 ([入力数, 中間数], 43 stddev=tf.sqrt(2.0 / 入力数))) 44 45 self.バイアス1 = tf.Variable(tf.truncated_normal \ 46 ([中間数], stddev=0.1)) 47 48 self.重み2 = tf.Variable(tf.truncated_normal \ 49 ([中間数, 出力数], 50 stddev=tf.sqrt(2.0 / 中間数))) 51 52 self.バイアス2 = tf.Variable(tf.truncated_normal \ 53 ([出力数], stddev=0.1)) 54 55 def 伝達処理(self, f枚数1, f枚数2, 入力値): 56 """引数の入力値には、tf.placeholderの4次元配列を渡す 57 変数[畳出力値]で畳み込み層の出力結果を受け取り 58 全結合の伝達処理をする""" 59 60 畳出力値 = 畳み込み層(f枚数1, f枚数2).伝達処理(入力値) 61 行サイズ = tf.size(畳出力値[0]) 62 全結合 = tf.reshape(畳出力値, [-1, 行サイズ]) 63 64 w1 , b1 = self.重み1, self.バイアス1 65 w2 , b2 = self.重み2, self.バイアス2 66 67 一層目 = tf.matmul(全結合, w1) + b1 68 活性化1 = tf.nn.relu(一層目) 69 ドロップアウト1 = tf.nn.dropout(活性化1, self.キープ率) 70 71 二層目 = tf.matmul(ドロップアウト1, w2) + b2 72 活性化2 = tf.nn.relu(二層目) 73 出力層 = tf.nn.softmax(活性化2) 74 75 return 出力層 76 77 def 欠損関数(self, 入力値, 正解ラベル): 78 """交差エントロピーを使用 79 tf.clip_by_valueで出力がnanにならないように対策""" 80 81 出力値 = self.伝達処理(32, 64, 入力値) 82 欠損値バッチ = -tf.reduce_sum(正解ラベル * tf.log(tf.clip_by_value\ 83 (出力値, 1e-10, 1.0)), 84 axis=1) 85 交差エントロピー = tf.reduce_mean(欠損値バッチ) 86 return 交差エントロピー 87 88 def 正解率(self, 入力値, 正解ラベル): 89 出力値 = self.伝達処理(32, 64, 入力値) 90 真理値判定 = tf.equal(tf.argmax(出力値, 1), tf.argmax(正解ラベル, 1)) 91 正解率 = tf.reduce_mean(tf.cast(真理値判定, tf.float32)) 92 return 正解率 93 94 def 確率的勾配下降(self, 入力値, 正解ラベル): 95 欠損値 = self.欠損関数(入力値, 正解ラベル) 96 勾配下降 = tf.train.AdamOptimizer(0.01). minimize(欠損値) 97 return 勾配下降 98 99 def 学習処理(self, f枚数1, f枚数2): 100 with tf.Session() as セッション: 101 セッション.run(tf.global_variables_initializer()) 102 103 画像サイズ = tf.placeholder(tf.float32, [None, 784]) 104 正解サイズ = tf.placeholder(tf.float32, [None, 10]) 105 入力値 = tf.reshape(画像サイズ, [-1, 28, 28 ,1]) 106 107 self.キープ率 = tf.placeholder(tf.float32) 108 109 i = 0 110 for _ in range(10000): 111 i += 1 112 バッチ番号 = np.random.choice(60000, 50) 113 k入力バッチ = x_train[バッチ番号] 114 k正解バッチ = t_train[バッチ番号] 115 n = セッション.run(self.確率的勾配下降(入力値, 正解サイズ), 116 feed_dict={画像サイズ:k入力バッチ, 117 正解サイズ:k正解バッチ, 118 self.キープ率:0.5}) 119 120 if i == 100: 121 print(n) 122 123 124net = 全結合層(3136,1024,10) 125net.学習処理(32, 64)

自分に判りやすいように、畳み込み層と全結合層を分けて書いています

このコードを実行するとtf.global_variables_initializer()で初期化出来ていないという趣旨のエラーが出ます

それともインスタンス変数で初期化するのはあまり望ましくない事なのでしょうか?

わかる方いらしたらよろしくお願いします><

追記
結構前の質問ですが、自分のしたい感じの事が出来たので、一応追記しておきます。

python

1mport tensorflow as tf 2import numpy as np 3import モデル 4import 関数 5from dataset.mnist import load_mnist 6 7class mnist: 8 def __init__(self,入力形状, 正解形状, f枚数, 中間数, 学習率): 9 self.セッション = tf.Session() 10 self.入力ホルダ = tf.placeholder(tf.float32, 入力形状) 11 self.正解ホルダ = tf.placeholder(tf.float32, 正解形状) 12 self.キープ率 = tf.placeholder(tf.float32) 13 14 """畳み込み層のパラメーター""" 15 self.f1 = tf.Variable(tf.truncated_normal([3, 3, 1, f枚数], 16 stddev=0.01)) 17 self.fb1 = tf.Variable(tf.truncated_normal([f枚数], 18 stddev=0.01)) 19 self.f2 = tf.Variable(tf.truncated_normal([3, 3, f枚数, f枚数], 20 stddev=0.01)) 21 self.fb2 = tf.Variable(tf.truncated_normal([f枚数], 22 stddev=0.01)) 23 24 self.畳み込み出力 = モデル.cnn_batch_relu(self.入力ホルダ, 25 self.f1, self.fb1, 26 self.f2, self.fb2) 27 28 """全結合層のパラメーター""" 29 入力数 = tf.size(self.畳み込み出力[0]) 30 全結合 = tf.reshape(self.畳み込み出力, [-1, 入力数]) 31 出力数 = 正解形状[1] 32 33 self.重み1 = \ 34 tf.Variable(tf.truncated_normal([入力数,中間数], 35 stddev=tf.sqrt(2.0 / tf.cast(入力数, tf.float32)))) 36 self.バイアス1 = tf.Variable(tf.truncated_normal([中間数],stddev=0.01)) 37 38 self.重み2 = \ 39 tf.Variable(tf.truncated_normal([中間数, 出力数], 40 stddev= 0.01)) 41 self.バイアス2 = tf.Variable(tf.truncated_normal([出力数], stddev=0.01)) 42 43 self.出力層 = モデル.fcn_batch_relu(self.重み1, self.バイアス1, 44 self.重み2, self.バイアス2, 45 全結合, self.キープ率) 46 47 self.欠損値 = 関数.二乗和誤差(self.出力層, self.正解ホルダ) 48 self.勾配下降 = \ 49 tf.train.GradientDescentOptimizer(学習率).minimize(self.欠損値) 50 self.セッション.run(tf.global_variables_initializer()) 51 52 def 出力層run(self, 入力値, キープ率): 53 return self.セッション.run(self.出力層, 54 feed_dict={self.入力ホルダ:入力値, 55 self.キープ率:キープ率}) 56 57 58 def 欠損値run(self, 入力値, 正解ラベル, キープ率): 59 return self.セッション.run(self.欠損値, 60 feed_dict={self.入力ホルダ:入力値, 61 self.正解ホルダ:正解ラベル, 62 self.キープ率:キープ率}) 63 64 def 正解率run(self, 入力値, 正解ラベル, キープ率): 65 出力層 = self.出力層run(入力値, キープ率) 66 正解率 = 関数.分類正解率(出力層, 正解ラベル) 67 return self.セッション.run(正解率, 68 feed_dict={self.入力ホルダ:入力値, 69 self.正解ホルダ:正解ラベル, 70 self.キープ率:キープ率}) 71 72 def 勾配下降run(self, 入力値, 正解ラベル, キープ率): 73 self.セッション.run(self.勾配下降, 74 feed_dict={self.入力ホルダ:入力値, 75 self.正解ホルダ:正解ラベル, 76 self.キープ率:キープ率}) 77 78 79(入力値, 正解ラベル), (t入力値, t正解ラベル) = load_mnist(flatten=True, 80normalize=False, one_hot_label=True) 81 82network = mnist([None, 28, 28, 1], [None, 10], 50, 2024, 0.0001) 83 84入力値 = 入力値.reshape(60000, 28, 28, 1) 85t入力値 = t入力値.reshape(10000, 28, 28, 1) 86学習回数 = 50000 87バッチsize = 100 88 89for _ in range(学習回数): 90 ミニバッチ = np.random.choice(60000, バッチsize) 91 入力ミニバッチ = 入力値[ミニバッチ] 92 正解ミニバッチ = 正解ラベル[ミニバッチ] 93 network.勾配下降run(入力ミニバッチ, 正解ミニバッチ, 0.5) 94 95 if _%200 == 0: 96 欠損値リスト = [] 97 正解率リスト = [] 98 start = 0 99 end = 1001 100 for i in range(10): 101 欠損値 = network.欠損値run(t入力値[start:end], 102 t正解ラベル[start:end], 103 1.0) 104 105 正解率 = network.正解率run(t入力値[start:end], 106 t正解ラベル[start:end], 107 1.0) 108 109 欠損値リスト.append(欠損値) 110 正解率リスト.append(正解率) 111 start += 1000 112 end += 1000 113 114 print(len(欠損値リスト)) 115 print(len(正解率リスト)) 116 print(_, "欠損値", np.sum(欠損値リスト) / 10) 117 print(_, "正解率", np.mean(正解率リスト))

インスタンス変数にtf.Sessionとtf.global_variables_initializerを置く事で、前回のエラーを回避しつつ、session.runもうまく起動する事が出来ました。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2017/06/26 01:05

確かにクラスを用いてはいますが、これはオブジェクト指向と呼べるようなものではないです。一旦オブジェクト指向への試みを置いておいて、べた書きしたときの動向を調査してみてください。
退会済みユーザー

退会済みユーザー

2017/06/26 04:15

コメントありがとうございます! なるほど自分の認識がまだまだ甘かったようですね 申し訳ないです。オブジェクト指向というよりまとまりのあるコードをクラスで実装したいと思っていました。 ベタ書きした時の動向を調査というのはどういう意味でしょうか... 理解できなくてすいません><
LouiS0616

2017/06/26 05:36

クラスや関数のことは一旦忘れて、愚直にスクリプトを書いていってください。今の状態だと、コードの書き方に問題があるのか、Tensorflowの使い方に問題があるのか特定が困難です。新しいことを二つ同時に試すのはよした方が良いです。
LouiS0616

2017/06/26 05:38

オブジェクト指向に関してもツッコミどころは多くありますが、特に一番面白い(悪意はないですよ)のは全結合層が畳込み層を継承していることです。これは、「全結合層は畳込み層の一種である」と断言しているのと同じです。
退会済みユーザー

退会済みユーザー

2017/06/26 10:07

mnistに対して高精度を出すcnnなら愚直に書いたコードで実装した事はあります。 だから今度は、同じモデルのcnnをクラスを使って実装しようかなと試みてたのですが、まだ早いでしょうか?
LouiS0616

2017/06/26 10:25

さきにmnistのコードは試されていたのですね、失礼しました。ただ、このように問題が発生している以上、まだ理解が浅かったと解釈するのが妥当かと思います。うまくいかないときに、一歩立ち返っていろいろ試してみるのは大切なことです。
退会済みユーザー

退会済みユーザー

2017/06/26 10:49

アドバイスありがとうございます。そうですね もっとtensorflowとクラスで何が出来るのかを一つずつ試しながら、再度取り組もうと思います。
guest

回答2

0

ベストアンサー

処理がどういう順番で行われるのかわからないまま書いていることが問題です。
あと、TensorflowではPythonのクラスインスタンスの生成と無関係に変数の管理がされますが、それを考慮していないクラス設計になっているので、クラスとして使えないですね(これはすでにコメントで指摘があるとおりですが)。

処理の順番はこうなっています。

末尾の
net = 全結合層(3136, 1024, 10)
が実行されて全結合層の変数(Variable)が宣言される

net.学習処理(32, 64)が実行される

全結合層.学習処理を呼び出す
sessionスタート
global_variables_initializer でVariableの初期化
(略)
全結合層.確率的勾配下降を呼び出す
全結合層.確率的勾配下降の冒頭で全結合層.欠損関数を呼び出す
全結合層.欠損関数の冒頭で全結合層.伝達処理を呼び出す
全結合層.伝達処理の冒頭で 畳み込み層クラスのインスタンスを初期化する
畳み込み層クラスの __init__ メソッドで 畳み込み層の変数(Variable)が宣言される

となります。

global_variables_initializer の実行が、畳み込み層の変数(Variable)が宣言 より前 なので当然エラーになります。

簡単に、こう直せばいい、というようなものではありませんでしたので、事実の指摘のみで失礼します。

投稿2017/06/26 05:51

quickquip

総合スコア11029

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/26 10:34

回答ありがとうございます! どのような順番で処理されていくのかもっと意識しないといけないようですね... 自分が思ってた以上にこれを修正するのは難しいのですね 素直にインスタンス変数にパラメーターを置かない事にします
guest

0

実行環境がないため、推測になってしまいますが・・・
すみません、回答が全く的ハズレでした。

改めてコードを追ってみました。
まず全結合層が畳み込み層クラスを継承していますが、この継承に全く意味がありません。
無意味な継承のために読み手が非常に混乱します。

伝達処理で畳み込み層のインスタンスを生成しており、そこで__init__が呼ばれてます、quiquiさんのご指摘の通りですね。

うーん、オブジェクト指向以前にPython(というかプログラム言語)の基本的な勉強をしましょう。
全くの独学なのでしょうか?
もし近くにPythonが分かる方がいるのであれば、少しコードレビューをしてもらった方がいいと思います。


あとエラーが出た場合は必ずエラー文だけではなくトレースバックも貼って下さい。
どこの行でエラーが出たのがわからないと、原因の推測が非常に困難です。

投稿2017/06/26 05:24

編集2017/06/26 10:15
pashango2

総合スコア930

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pashango2

2017/06/26 05:31

> それともインスタンス変数で初期化するのはあまり望ましくない事なのでしょうか? インスタンス変数でグローバル変数(グローバル環境?)を初期化するのは望ましくありませんね。 たぶんクラスのインスタンスとグローバル環境はライフサイクルが違うのではないかと思います。
退会済みユーザー

退会済みユーザー

2017/06/26 10:24

回答ありがとうございます なるほど、まだまだ継承の使い所がわかっていないようですね... 初期化されていないのは先にインスタンス変数が呼ばれるからなんですね。 となればこの問題を修正するのは容易ではなさそうですね... python所かプログラムの相談を出来る人はいません...完全な独学となります すいません、次からトレースバックも貼るように気を付けます>< またこの質問も修正しておきます
pashango2

2017/06/26 10:40

なるほど完全な独学なのですね、ここまで独学なのであればかなり努力されたのだと思います。 可能であれば勉強会などでレビューしてもらい、相談できる環境を作った方が良いように思います。 まぁここでも相談でもよいと思いますが。 がんばってくださいね。
退会済みユーザー

退会済みユーザー

2017/06/26 11:21

人と触れ合う事でモチベーションにも繋がりますし、勉強会には少し興味があったので、視野に入れてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問