TensorFlowのFizzBu​​zz

インタビュアー :こんにちは、コーヒーか何か他にいかがですか? 休憩が必要ですか?







:いいえ、私はすでに十分なコーヒーを飲んだと思います!







インタビュアー :素晴らしい、素晴らしい。 ボードにコードを書くことについてどう思いますか?







me :このようにコードを書くだけです!







インタビュアー :...







:それは冗談でした。







インタビュアー :OK、それでフィズバズの問題を知っていますか?







:...







インタビュアー :それはイエスかノーですか?







me :「これを聞いているなんて信じられない」みたいなものです。







インタビュアー :わかりました。1から100までの数字を印刷する必要があります。数字が3で割り切れる場合にのみ、「fizz」という単語を印刷します。







me :このタスクを知っています。







インタビュアー :さて、このタスクを完了できない候補者は、私たちとうまくやっていけません。







:...







インタビュアー :これはマーカーとスポンジです。







:[数分考えた]







インタビュアー :始めるには助けが必要ですか?







:いや、いや、それでいい。 それでは、いくつかの標準的なインポートから始めましょう。







import numpy as np import tensorflow as tf
      
      





インタビュアー :ええと、あなたはfizzbuzzの問題を正しく理解しましたよね?







:そうです。 モデルについて説明しましょう。 ここでは、1つの隠れ層を持つ単純な多層パーセプトロンが適していると思います。







インタビュアー :パーセプトロン?







me :または、ニューラルネットワーク。 数字を入力します。出力は、その数字の正しい「fizzbuzz」表現です。 特に、すべての入力を「アクティベーション」のベクトルに変換する必要があります。 1つの簡単な方法は、バイナリに変換することです。







インタビュアー :バイナリルック?







:はい、まあ、あなたは知っている、1と0? 次のようなもの:







 def binary_encode(i, num_digits): return np.array([i >> d & 1 for d in range(num_digits)])
      
      





インタビュアー :[1分間掲示板を見る]







me :そして、出力は数値を表すfizzbuzzのユニタリーコーディングになります。最初の位置は「そのまま印刷」を意味し、2番目は「fizz」を意味します。







 def fizz_buzz_encode(i): if i % 15 == 0: return np.array([0, 0, 0, 1]) elif i % 5 == 0: return np.array([0, 0, 1, 0]) elif i % 3 == 0: return np.array([0, 1, 0, 0]) else: return np.array([1, 0, 0, 0])
      
      





インタビュアー :わかりました、それで十分のようです。







:はい、あなたは正しいです、これは設定するのに十分です。 次に、ネットワークをトレーニングするためのデータを生成する必要があります。 トレーニングに1〜100の数字を使用するのは公平ではないので、残り1024までのすべての数字でトレーニングしましょう。







 NUM_DIGITS = 10 trX = np.array([binary_encode(i, NUM_DIGITS) for i in range(101, 2 ** NUM_DIGITS)]) trY = np.array([fizz_buzz_encode(i) for i in range(101, 2 ** NUM_DIGITS)])
      
      





インタビュアー :...







me :ここで、モデルをテンソルフローに適合させる必要があります。 すぐにどの層の厚さを取るべきかよくわかりません。







インタビュアー :...







:はい、おそらく100がより良いでしょう。 これは後からいつでも変更できます。







 NUM_HIDDEN = 100
      
      





幅がNUM_DIGITSの入力変数と、幅が4の出力変数が必要です。







 X = tf.placeholder("float", [None, NUM_DIGITS]) Y = tf.placeholder("float", [None, 4])
      
      





インタビュアー :これをどこまで進めるつもりですか?







me :ああ、2つのレイヤー-1つの非表示レイヤーと1つの出力レイヤー。 ニューロンにランダムに初期化された重みを使用しましょう:







 def init_weights(shape): return tf.Variable(tf.random_normal(shape, stddev=0.01)) w_h = init_weights([NUM_DIGITS, NUM_HIDDEN]) w_o = init_weights([NUM_HIDDEN, 4])
      
      





そして、モデルを定義する準備ができました。 前に言ったように、1つの隠されたレイヤー、そして、それでは、ReLUアクティベーションを使用してみましょう。







 def model(X, w_h, w_o): h = tf.nn.relu(tf.matmul(X, w_h)) return tf.matmul(h, w_o)
      
      





コスト関数としてソフトマックスのクロスエントロピーを使用し、最小化することができます。







 py_x = model(X, w_h, w_o) cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(py_x, Y)) train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
      
      





インタビュアー :...







me :そしてもちろん、予測は最大の出力になります:







 predict_op = tf.argmax(py_x, 1)
      
      





インタビュアー :あなたが迷子になるまで、あなたが解決しなければならなかった問題は、1から100までの数字のフィズバズを生成することでした







me :素晴らしい点、predict_op関数は0〜3の数値を返しますが、「fizz buzz」出力が必要です。







 def fizz_buzz(i, prediction): return [str(i), "fizz", "buzz", "fizzbuzz"][prediction]
      
      





インタビュアー :...







me :モデルをトレーニングする準備ができました。 テンソルフローセッションを発生させ、変数を初期化します。







 with tf.Session() as sess: tf.initialize_all_variables().run()
      
      





たとえば、1000のトレーニング期間を開始しますか?







インタビュアー :...







:はい、おそらくこれでは十分ではないでしょう-確かに10,000にしましょう。







また、トレーニングデータには一貫性がありますが、これは気に入らないので、各反復に入れましょう。







 for epoch in range(10000): p = np.random.permutation(range(len(trX))) trX, trY = trX[p], trY[p]
      
      





そして、各時代はパックでトレーニングしますが、よくわかりませんが、128エントリを許可します。







 BATCH_SIZE = 128
      
      





その結果、各パスは次のようになります。







  for start in range(0, len(trX), BATCH_SIZE): end = start + BATCH_SIZE sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end]})
      
      





トレーニングデータのエラーを推測できます。なぜだろうか?







  print(epoch, np.mean(np.argmax(trY, axis=1) == sess.run(predict_op, feed_dict={X: trX, Y: trY})))
      
      





インタビュアー :本気ですか?







me :はい、精度がどの程度向上しているかを見るのは非常に便利です。







インタビュアー :...







:だから、モデルが訓練された後、バズの時間。 入力は1〜100のバイナリコーディング番号のみです。







 numbers = np.arange(1, 101) teX = np.transpose(binary_encode(numbers, NUM_DIGITS))
      
      





そして、結論は出力モデルに適用されたfizz_buzz関数だけです:







 teY = sess.run(predict_op, feed_dict={X: teX}) output = np.vectorize(fizz_buzz)(numbers, teY) print(output)
      
      





インタビュアー :...







:それがあなたのフィズバズです!







インタビュアー :それで十分です。 ご連絡いたします。







I :お問い合わせ、有望だと思います。







インタビュアー :...







追記



私はこの仕事に就きませんでした。 しかし、私は実際にこのコード( Githubコード )を実行しようとしましたが、わずかに不正確な出力を与えることが判明しました! 機械学習に感謝します!







 In [185]: output Out[185]: array(['1', '2', 'fizz', '4', 'buzz', 'fizz', '7', '8', 'fizz', 'buzz', '11', 'fizz', '13', '14', 'fizzbuzz', '16', '17', 'fizz', '19', 'buzz', '21', '22', '23', 'fizz', 'buzz', '26', 'fizz', '28', '29', 'fizzbuzz', '31', 'fizz', 'fizz', '34', 'buzz', 'fizz', '37', '38', 'fizz', 'buzz', '41', '42', '43', '44', 'fizzbuzz', '46', '47', 'fizz', '49', 'buzz', 'fizz', '52', 'fizz', 'fizz', 'buzz', '56', 'fizz', '58', '59', 'fizzbuzz', '61', '62', 'fizz', '64', 'buzz', 'fizz', '67', '68', '69', 'buzz', '71', 'fizz', '73', '74', 'fizzbuzz', '76', '77', 'fizz', '79', 'buzz', '81', '82', '83', '84', 'buzz', '86', '87', '88', '89', 'fizzbuzz', '91', '92', '93', '94', 'buzz', 'fizz', '97', '98', 'fizz', 'fizz'], dtype='<U8')
      
      





おそらく、より深いニューラルネットワークを使用する必要があります。








All Articles