説明というか現状までの理解については次回以降にして、今はとにかく結果が得られるコードが欲しいのでそれらしい物を書いた。
import tensorflow as tf import numpy as np from tensorflow.keras.optimizers import RMSprop # モデル作成 # Define the model. model = tf.keras.models.Sequential([ tf.keras.layers.InputLayer(input_shape=(2,)), # 入力層 要素数1、内容「2」のタプル tf.keras.layers.Dense(units=4, activation='sigmoid'), tf.keras.layers.Dense(units=4, activation='sigmoid'), tf.keras.layers.Dense(units=1, activation='linear') # 出力層 1出力。1出力の時はsoftmaxは使えない ]) model.compile( optimizer=RMSprop(), loss='mse' ) # トレーニング用入力 XY = np.array( [[0.0,0.0], [0.0,1.0], [1.0,0.0], [1.0,1.0]] ) # 正解データ T = np.array( [[0.0], [1.0], [1.0], [0.0]] ) # トレーニング model.fit(XY, T, epochs=3000, batch_size=4) print("------------------------------") # 出力値をしきい値処理 threshold = 0.5 # 検証用データをモデルに入力し、出力(予測値)を取り出す predict_y = model.predict( np.array( [[0,0]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[1,0]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[0,1]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[1,1]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) )
import tensorflow as tf import numpy as np from tensorflow.keras.optimizers import RMSprop # モデル作成 # Define the model. model = tf.keras.models.Sequential([ tf.keras.layers.InputLayer(input_shape=(2,)), # 入力層 要素数1、内容「2」のタプル tf.keras.layers.Dense(units=4, activation='sigmoid'), tf.keras.layers.Dense(units=4, activation='sigmoid'), tf.keras.layers.Dense(units=2, activation='softmax') # 出力層 softmaxの時は2個以上の出力 ]) model.compile( optimizer=RMSprop(), loss='mse' ) # トレーニング用入力 XY = np.array( [[0.0,0.0], [0.0,1.0], [1.0,0.0], [1.0,1.0]] ) # 正解データ (One Hot表現) T = np.array([[0.0, 1.0], [1.0, 0.0], [1.0, 0.0], [0.0, 1.0]]) # トレーニング model.fit(XY, T, epochs=3000, batch_size=4) print("------------------------------") # 出力値をしきい値処理 threshold = 0.5 # 検証用データをモデルに入力し、出力(予測値)を取り出す predict_y = model.predict( np.array( [[0,0]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[1,0]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[0,1]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) ) predict_y = model.predict( np.array( [[1,1]] ) ) print( predict_y , (predict_y > threshold).astype(np.int) )
Denseを調べます
http://marupeke296.com/IKDADV_DL_No7_dense.html
ご注文は TensorFlow 2.x ですか??
https://hmx.hatenablog.jp/entry/2020/04/26/000000
光軒の集い
https://www.kouken-party.info/2017/10/25/python%E3%81%A8keras%E3%81%A7xor/
kerasでOne-hotのラベルを作成する
https://qiita.com/okj15/items/f081ac0928540f1579b5
【Python/Keras】ニューラルネットで論理演算(XOR)の学習
https://algorithm.joho.info/machine-learning/python-keras-neural-network-and-or/
Cannot train a neural network solving XOR mapping
https://stackoverflow.com/questions/34311586/cannot-train-a-neural-network-solving-xor-mapping
この記事の目的はとにかく検索すると1.x系列の情報がまずヒットするので手の届くところに最小限の2.x系列で動くサンプルを置いておく事にある。
import tensorflow as tf a = tf.constant(10.1, dtype=tf.float32, name="a") b = tf.constant(20.2, dtype=tf.float32, name="b") c = tf.Variable(30.3, dtype=tf.float32, name="c") d = tf.Variable(40.4, dtype=tf.float32, name="d") # @tf.functionを付けると関数のような形で計算グラフを書ける @tf.function def f(): divop = tf.divide(a,b,name="a-div-b") addop = tf.math.add(divop,c,name="div-add-c") d.assign(addop,name="d-assign-add") # ここでrun f() tf.print(d)
import tensorflow as tf a = tf.constant(10.1, dtype=tf.float32, name="a") b = tf.constant(20.2, dtype=tf.float32, name="b") c = tf.Variable(30.3, dtype=tf.float32, name="c") d = tf.Variable(40.4, dtype=tf.float32, name="d") # @tf.functionを使わない場合。 divop = tf.divide(a,b,name="a-div-b") addop = tf.math.add(divop,c,name="div-add-c") d.assign(addop,name="d-assign-add") tf.print(d)
@tf.functionで書かないTensorBoard用出力の方法がどうしてもわからなかったのでとりあえず使ったもの。
この例ではグラフをカレントディレクトリの./output/に出力する
import tensorflow as tf import os
logdir = './output' writer = tf.summary.create_file_writer(logdir)
################################### a = tf.constant(10.1, dtype=tf.float32, name="a") b = tf.constant(20.2, dtype=tf.float32, name="b") c = tf.Variable(30.3, dtype=tf.float32, name="c") d = tf.Variable(40.4, dtype=tf.float32, name="d") @tf.function def f(): divop = tf.divide(a,b,name="a-div-b") addop = tf.math.add(divop,c,name="div-add-c") d.assign(addop,name="d-assign-add") ###################################
with writer.as_default(): tf.summary.graph(f.get_concrete_function().graph) writer.close()
以下のコマンドでtensorBoardを起動し、ブラウザでhttp://localhost:6006/ を開く。
なぜかconstantの名前が消えてx,yになる上にVariableは表示すらされない。散々調べたが表示する方法が見つからなかった。
計算グラフの表示に関してはtf.summary.trace_on(graph=True,profiler=False) でもできる。ちなみにprofiler=Trueにしたら私の環境ではエラーが出たので試せていない。
import tensorflow as tf import os logdir = './output' writer = tf.summary.create_file_writer(logdir)
tf.summary.trace_on(graph=True,profiler=False)
################################### a = tf.constant(0.01, dtype=tf.float32, name="a") s = tf.Variable(0.0, dtype=tf.float32, name="s") v = tf.Variable(0.0, dtype=tf.float32, name="v") @tf.function def f(): s.assign_add(a) v.assign(tf.sin(s)) ################################### f() # 一度は計算グラフを走らせないと出力できない with writer.as_default():
tf.summary.trace_export("summary", step=0, profiler_outdir="./output")
tf.summary.trace_off()
writer.close()
tensorflowはニューラルネットワークを組むために作られた計算グラフ作成ツールであり(という理解をしている)、同じ計算グラフを何度もrunさせて重みを調整していく事を想定しているので、繰り返した場合の値の変化をtensorBoardで確認してみる。
import tensorflow as tf import os logdir = './output' writer = tf.summary.create_file_writer(logdir) ################################### a = tf.constant(0.01, dtype=tf.float32, name="a") s = tf.Variable(0.0, dtype=tf.float32, name="s") v = tf.Variable(0.0, dtype=tf.float32, name="v") @tf.function def f(): s.assign_add(a) v.assign(tf.sin(s)) ################################### with writer.as_default(): for STEP in range(1000): # 1000 回繰り返し f() # 計算グラフ実行 tf.summary.scalar("s",s,step=STEP) # scalarを出力するときは、何回目のループなのかを表すstepを指定しなければいけない tf.summary.scalar("v",v,step=STEP) writer.flush() writer.close()
Blender 2.9からBlender 2.79へデータを変換する方法。Blender 2.93側でCtrl+C(コピー)→Blender 2.79側でCtrl+V(貼り付け)をすれば2.79に取り込むことができる。
Blender 2.7系はデフォルトでBlender RenderだったりするのでうっかりCyclesにし忘れるとレンダリングできないので注意。
Editモードで[U]キーを押してunwrapする
以下のHDRIをダウンロードしてWorldに適用する。その後、レンダリング結果の背景が空だけになるようにカメラと背景の関係を調整する
https://hdrihaven.com/hdri/?h=snowy_park_01
https://www.textures.com/download/PBR0234/133290
コントローラー用Sphereの状態に応じて地形を変化させる
VertexWeightProximityのFalloff→TypeをSmoothなどにすると地形がより自然になる。
SphereをMergeして点にしてしまえば、Sphereが表示されなくなる。影響範囲も若干変わる
標高はDisplacementモディファイアのStrengthとMidlevelで調節する。
コントローラ用の頂点を押し出して地形を複雑にする
まずPlaneを配置し、16分割する。地形本体用。
用意出来たらVertex Groupを作成しMountain-Areaと名前を付け、全ての頂点をAssignする。
次にSphereを追加し、Editモードで1/5のサイズにする。地形の形状のコントローラー用。このサイズ変更はradiusの値を変更しても勿論いいが、ObjectモードでScaleすると結果が変わってしまうので注意。地形の形状がコントローラーの変換行列の影響を受けるため。
Planeに対してDisplaceモディファイアを追加。テクスチャにはCloudsを使用。
Coordinatesにはコントローラー用のSphereを設定し、Vertex GroupにMountain-Areaを設定。
ここまでで、コントローラ用Sphereを移動すればDisplacementが位置や回転に応じて変形する。
VertexWeightProximityモディファイアを追加。PlaneのMountain-Areaの頂点を、Shpereとの距離で決定する。Lowest=1,Highest=0に設定すると、Sphereに近い位置の頂点ほど強い影響を受け、遠い位置の頂点ほど影響しなくなる。
一番上にSubdivision Surfaceを追加する。
ずっと以前にパスワード付き展開を忘れていたことを思い出した。
基本は下記で、使用関数を zip_fopen_encrypted にする。
#include <zip.h> #include <iostream> #pragma comment(lib,"zip.lib") #pragma warning(disable:4996) void compress_encrypted(); void uncompress_encrypted(); //ファイルを圧縮 int main(int argc, char* argv[]) { //compress_encrypted(); uncompress_encrypted(); int i; std::cin >> i; return 0; }
void uncompress_encrypted() { // パスワードの定義 const char* thePassWord = "j6KY4cwC"; // ZIPファイルを読み取り専用で開く int errorp; zip_t* zipper = zip_open(R"(C:\test\out.zip)", ZIP_RDONLY, &errorp); // ZIP内のファイルの個数を取得 zip_int64_t num_entries = zip_get_num_entries(zipper, 0); // ZIP内のファイルの各ファイル名を取得 std::cout << "count: " << num_entries << std::endl; for (zip_int64_t index = 0; index < num_entries; index++) { std::cout << "[" << index << "]" << zip_get_name(zipper, index, ZIP_FL_ENC_RAW) << std::endl; } // ZIP内の2番目のファイルに関する情報を取得する struct zip_stat sb; zip_int64_t index = 2; zip_stat_index(zipper, index, 0, &sb); // 2番目のファイルのファイルサイズと同じメモリを確保する char* contents = new char[sb.size]; // 2番目のファイルの内容をメモリに読み込む zip_file* zf = zip_fopen_encrypted(zipper, sb.name, 0, thePassWord); zip_fread(zf, contents, sb.size); zip_fclose(zf); zip_close(zipper); ////////////////// // ファイル名を出力できる形に変更 // ファイル一覧は階層構造をしておらず、ディレクトリ区切りは'/'で直接出力できないので // ファイル名中の'/'を'-'に置き換える。 // 本来なら再帰的にディレクトリを作るなどすべき。 std::string target = sb.name; for (size_t i = 0; i < target.size(); i++) { if (target[i] == '/') { target[i] = '-'; } } // ////////////////// // 解凍したファイルを作成 std::string outname = R"(C:\test\)" + target; FILE* of = fopen(outname.c_str(), "wb"); fwrite(contents, 1, sb.size, of); fclose(of); }
void compress_encrypted() { int errorp; zip_t* zipper = zip_open(R"(C:\test\out.zip)", ZIP_CREATE | ZIP_EXCL, &errorp); // パスワードの定義 const char* thePassWord = "j6KY4cwC"; zip_source_t* source; zip_int64_t iIndex; source = zip_source_file(zipper, R"(C:\test\data\snail1.png)", 0, 0); iIndex = zip_file_add(zipper, R"(snail1.png)", source, ZIP_FL_ENC_RAW); zip_file_set_encryption(zipper, iIndex, ZIP_EM_AES_128, thePassWord);//パスワードを指定 source = zip_source_file(zipper, R"(C:\test\data\snail2.png)", 0, 0); iIndex = zip_file_add(zipper, R"(snail2.png)", source, ZIP_FL_ENC_RAW); zip_file_set_encryption(zipper, iIndex, ZIP_EM_AES_128, thePassWord);//パスワードを指定 source = zip_source_file(zipper, R"(C:\test\data\snail5.png)", 0, 0); iIndex = zip_file_add(zipper, R"(snail5.png)", source, ZIP_FL_ENC_RAW); zip_file_set_encryption(zipper, iIndex, ZIP_EM_AES_128, thePassWord);//パスワードを指定 zip_close(zipper); }
使用する関数がshared_ptrを受け取るようになっていた場合(下記my_useful_function)、当然呼び出すときにshared_ptrでなければいけないが、そのポインタがshared_ptrで管理されていない場合。
unique_ptrであればrelease関数で管理を放棄できるがshared_ptrにはないらしい。
ちなみに無理やりshared_ptrにしてしまうとそのスマートポインタの破棄と同時にdeleteが走るので決してやってはいけない。
#include <iostream> struct MyObject { int value; ~MyObject() { std::cout << "destructor" << std::endl; } }; // この関数は社長の御子息が開発された大変優れたコードであり、開発者は常にこれを呼び出さなければならない。 // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void my_useful_function(std::shared_ptr<MyObject> ptr) { ptr->value = 5; } // この関数は先々代から脈々と受け継がれし伝統ある関数であり、MyObjectの生成には必ずこの関数を呼び出さなければならない。 // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す MyObject* my_great_factory() { return new MyObject; }
// 顧客側の要求仕様に則り、この関数の引数を変更してはならない // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void project_job(MyObject* pobect) { // 仕様変更によりmy_normal_functionでは要求を満たせなくなった // 旧コード my_normal_function(pobject) my_useful_function(pobect); //新コード 型が違って呼び出せない }
int main() { MyObject* pmyo = my_great_factory(); project_job(pmyo); std::cout << pmyo->value; delete pmyo; }
スマートポインタにはdeleterを指定できるので、そこに何もしないラムダ関数を指定する。
// 顧客側の要求仕様に則り、この関数の引数を変更してはならない // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void project_job(MyObject* pobect) { // 仕様変更によりmy_normal_functionでは要求を満たせなくなった // 旧コード my_normal_function(pobject) // shared_ptrにする。deleterを指定し、何もしないことでpbojectの参照先が破棄されないようにする std::shared_ptr<MyObject> spobject(pobect, [](auto) {}); my_useful_function(spobject); //新コード shared_ptr型の引数を与える }
まずテスト用に以下のように関数宣言、定数の定義をしておく。
#include <iostream> #include <random> // 乱数用 constexpr int TESTCOUNT = 10; /////////////////////////// void cpp_rand_test_1(); void cpp_rand_test_2(); void cpp_rand_test_3(); void cpp_rand_test_4(); void cpp_rand_test_5(); /////////////////////////// int main() { cpp_rand_test_1(); //cpp_rand_test_2(); //cpp_rand_test_3(); //cpp_rand_test_4(); //cpp_rand_test_5(); }
// 疑似乱数 基本 void cpp_rand_test_1() { // *疑似乱数 // *初期シードが同じなら毎回同じ値が出る // *64bitの範囲が欲しいなら std::mt19937_64 std::mt19937 mt(0/*初期シード*/); for (size_t i = 0; i < TESTCOUNT; i++) std::cout << mt() << std::endl; }
// 範囲指定 , 一様乱数 void cpp_rand_test_2() { // 疑似乱数 std::mt19937 mt(0/*初期シード*/); // 0~5の範囲の一様乱数作成用 // float型が欲しいなら std::uniform_real_distribution<> std::uniform_int_distribution<> idistri(0, 5); for (size_t i = 0; i < TESTCOUNT; i++) std::cout << idistri(mt) << std::endl; }
// 正規分布乱数 void cpp_rand_test_3() { // 疑似乱数 std::mt19937 mt(0/*初期シード*/); // 正規分布乱数作成用 std::normal_distribution<> norm(50.0/*平均*/, 10.0/*分散*/); for (size_t i = 0; i < TESTCOUNT; i++) std::cout << norm(mt) << std::endl; }
// 非決定論的な乱数 void cpp_rand_test_4() { // 注意点: // *どんな値が出るか分からない // *遅い // *ハードウェアを使うのでプラットフォームによっては実装不可 // (実装できない場合は疑似乱数として動く) std::random_device rng; for (size_t i = 0; i < TESTCOUNT; i++) std::cout << rng() << std::endl; }
// 非決定論的な乱数をseedに疑似乱数を生成 void cpp_rand_test_5() { // 非決定論的な乱数 std::random_device rng; // 疑似乱数 std::mt19937 mt(rng()/*初期シード*/); for (size_t i = 0; i < TESTCOUNT; i++) std::cout << mt() << std::endl; }
「ページを Pocket に保存」「スクリーンショットを撮影」などは、自分にとって不要なので右クリックメニューから非表示にしたい。
about:configから設定する。実行すると「危険性を承知の上で使用する」の同意を求められるのでクリックする。
各設定項目の右側のチェックをクリックするとフラグが反転する。
「ページを Pocket に保存」 ... extensions.pocket.enabled
「スクリーンショットを撮影」... extensions.screenshots.disabled