ロボットの頭部をAIでデザインできないかと試してみたい ー3Dの畳込み層を使ってみるー
前回の試作では3Dモデル生成のためのGAN(敵対的生成ネットワーク)の構成は2次元の画像を生成するのと全く同じでした。3次元座標情報をさながら地球儀を紙の世界地図に展開するようなかたちで2次元に展開し、ネットワークに入力していたわけです。その後、GANの実装に使われているTensorFlowライブラリの仕様を調べていたらConv3DとかUpSampling3Dといった3次元情報を直接処理する層が用意されていることを知りました。それなら、Conv2Dの代わりにConv3D、UpSampling2Dの代わりにUpSampling3Dを使えば3次元データを直接学習、生成できるだろうということで試してみたのが今回の報告です。
前回は3次元空間上の点を極座標形式(r, θ,Φ)で表して n等分したθ,Φに対してrの値を計算して3Dモデルとしていました。今回はすなおに3次元空間上の座標を(x, y, z)で表現しn×n×n個の座標に対してそこに点があるかどうか(1~-1、値が大きいほどそこに点がある可能性が高いとする)を計算して3Dモデルとします。
問題は2次元から3次元になったことで学習に必要な計算量が飛躍的に増大したことです。普段使っているPCでは1回のバッチ分の計算にも1時間近くかかる始末、何千回の繰り返しなんてとてもおぼつかない。そのため今回の学習にはGoogle Colaboratory(略称: Colab)というクラウドサービスを使わせていただきました。連続して使用できる時間などに制限はありますが、アクセラレータ付きのサーバー上でPythonプログラムを無料で実行することができます。
それでもn=64(64×64×64)の分割ではすぐにリソース制限にひっかかってしまうので、今回はn=32(32×32×32)の分割で処理を行うことにしました。学習が終わればネットワークの重み係数のファイルをダウンロードして、3Dモデルの生成を自分のPCで行うことができます。100次元の値ランダム(1~-1)のベクトルを生成して生成用のネットワークで処理するのですが1個数十秒程度で3Dモデル(32×32×32のnumpy配列)が生成されます。
ノイズの消去や閾値処理等を行ってからOBJ形式に変換(点だけの情報に面情報を付加するプログラムを作成)したのが以下のような感じ。
ここから先は自分でプログラムを作るのはめんどくさいのでZBrushに読み込んで行うことにします。まず、離れ小島のような塊を削除してから左右対称に整形します。
自作のOBJ生成のロジックがいまいちでメッシュが汚いのでダイナメッシュをかけてスムーズにします。
前回よりはだいぶロボットの顔らしくなってる! そう思いたい..
以下にいくつか生成例を載せています。
頭部全体の輪郭が人の形っぽいものや、平べったいかたち、アンテナ(角?)っぽいものがついたもの、前回の極座標形式での生成よりもバリエーションが増えた気がします。
ロボットの頭部をAIでデザインできないかと試してみたい ー単純に適用してみたー
OBJ形式の3Dモデルをニューラルネットへの入力であるNumpy形式に変換するプログラム、逆にニューラルネットの出力のNumpy形式をOBJ形式に変換するプログラムを作ったので、参考書で定義されているGAN(敵対的生成ネットワーク)で3Dデータを生成してみました。学習データはThingiverseで見つけてきたロボットの3Dデータ。ガンダム、パシフィックリムなどのロボットの3DデータをZBrushで編集して頭部だけのデータを60体分集めました。これだけでは全然足りないので、1体分のデータを縦/横に少しずつ引き延ばして25のバリエーションを作成、全部で1500ほどを学習データ(1データは64×64次元、3チャンネル)として準備しました。
ニューラルネットの構成はセレブの顔を生成する例を何も考えずそのまま使用、人間が決めないといけないハイバーパラメータもそのまま使っています。GANではではランダムに発生させた3Dデータから出発してロボットの頭部っぽい3Dデータを生成するネットワークと本物の頭部(学習データ)と人工的に生成された頭部っぽい3Dデータを区別するネットワークが競い合って3Dモデルを発展させていきます。
で、試してみると学習の初期段階で生成されている3Dデータがこんな感じ。
そもそもなんのかたちにもなっていないという感じですが、学習プロセスを5000回ぐらい繰り返すと、以下のようななんか(?)のかたちにはなってきました。
「どこがロボットじゃーい!!?」と突っ込まれそうですが、ランダムノイズのようなデータからコンピュータが勝手にここまでの3Dデータを作ってくれるってすごいことのように思えます。
もう少し勉強していけばいろいろおもしろいことができそうです。
ロボットの頭部をAIでデザインできないかと試してみたい ーまだ始めたばかりですがー
以前に3Dモデルをプログラムで生成するツールを試作していましたが、今年はFusion 360でのモデリング作業が主となっていてなかなか手をつけることができませんでした。1年以上の間、こっちのアプローチの作業はしていない...
で、最近読んだのがこの本。与えられた画像や音声のパターンを認識するだけではなくて画像やテキストをニューラルネットワークで生成することができるんですね。
O'Reilly Japan - 生成 Deep Learning
生成される画像データは3次元の配列(縦×横×RGB)なんですが、じゃあ3次元の形状も大きさも定まった配列で表現できれば(そして十分な学習データが用意できれば)センスの有無に関係なくロボットの顔をデザインできる!
そう考えてまず、OBJ形式の3次元データを大きさ固定の配列で表すPythonプログラムを作ってみました。
- OBJデータに含まれる点の座標を極座標形式(r, θ,Φ)に変換
- 2π/配列サイズの単位でθとΦを離散化、該当するrの値を持つ2次元配列に格納
- RGBの値の代わりにθ、Φで決まるベクトル上で最初の点、2番目の点、3番目の点のrを格納していく
Thingiverseで見つけてきた3Dモデルはこんな感じ。
64×64×3の配列データに変換して、3Dグラフにプロットしてると以下のようになります。解像度64だとディテールまでは表現できないものの、大雑把な輪郭や特徴的な額のアンテナは再現できそうです。
学習用のデータを集めるのがたいへんそうだしそもそもニューラルネットの構成をまだ決めていないのですが、来年(2021年)はこの方向の試行も進めていきたいと思っています。
ロボット骨格にボディアーマーを装着する -次郎丸編-
1か月以上かかってしまいましたが、PETGフィラメントで出力したロボット骨格(前回投稿後に改良)にボディアーマーを装着しました。Fusion360上で大きさや位置の合わせをしながら設計していった(下図)のですが、骨格の動きとアーマーが干渉したり、出力してみると強度がたりなかったりで、ずいぶんと試作と廃棄を繰り返すことになりました。
下の写真で試作機がポーズをとった足元に転がっていいるのは完成までに犠牲になったパーツの亡骸(の一部)です。実機だったら開発中止になってますね。
アーマーは骨格にねじ止めしているので、脱着可能です。前と後ろはこんな感じ。現状、関節の裏側はどうしてもむき出しになってしまうのですが、ガンプラなんかではどう処理しているんだろう。
肩から上腕部分は、1軸(胸の内部に埋込み)、2軸、1軸の3つのジョイントで構成しています。両端のジョイントにアーマー部品をねじ止めしています。青いのはボールジョイントを挟みこんだときの緩衝材として塗ったリキッドゴムです。前回はシリコンゴムのチューブを切って貼り付けていたのを今回は違うやり方を試してみたのですが、結果は関節をぐりぐり動かしているうちにゴムがはがれてきてしまいいまいちでした。TPUフィラメントを試してみたいけど、Adventrer3ではヒートヘッドの温度がちょっと足りないかな、と考えあぐねているところです。
アーマーをつけたことによって関節の可動域が制限されてしまった部分(特に腰のあたり)もありますが、いちおうフルアーマー付きでポーズをとる段階になったので試作機に名前を付つけることにしました。
前回試作機PLR-18-01につけた名前をつけたのは「太郎丸」でした。
今 回の試作機PLR-23-01は「次郎丸」と命名しました。
ロボット骨格の関節可動範囲を改良
前回のBlogで紹介したロボット骨格を改良を続けています。今回は肩と脚のつけ根の関節の自由度を1つ増やしました。
ロボット骨格の関節はPETG製のパーツとバーツ同士を繋げるボルト/ナット、緩衝材として用いるシリコンゴムのチューブから成り立っています。構成は以下の3種類。
①肘や膝の関節に用いる1軸のジョイント
②腰の部分に用いる1軸のジョイント
③肩や脚の根本に用いる2軸のジョイント
③が今回骨格に追加した関節部品です。ボール型のジョイントをシリコンゴムの緩衝材で挟みボルト/ナットで締め付けています。ボール型ジョイントを使うことで2つの自由度を実現しています。以前に試したボールをスナップインではめ込む方法ではどうしてもポーズの保持力に不満が残るのでボルト/ナットを使うことにしました。
左の仮面ライダー1号の変身ポーズでは肩の関節が大きく曲がるようになったので手を顔の前までもってくることができるようになっています。ちなみに前バージョンで同じポーズをとろうとしても下の写真のようになってしまいます。
ロボット骨格 新バージョン
連休の間にロボット骨格の新バージョンを制作しました。関節の保持力を高めるために新素材(金属)を採用しています。関節の回転軸に8mm~10mmの長さのボルトを使い、ナットでしっかりとめてPETGで出力したパーツを押さえつけています。
いったん決めたポーズがくずれてしまうことはないし、金属部分がアクセントになって見た目もいい感じです(と思っています)。
ただ、上の骨格だとアーマー(胸から背中にかけて)を取り付けたとき肩関節の動きが大きすぎて干渉しそうなので下の写真のようなタイプBを制作しました。
タイプA/B両方を使っていろいろポーズを試しています。
うーん、肩関節/上腕あたりの自由度をもう1つ増やしたいなという感じ。具体的には今は仮面ライダー1号の変身ポーズがとれない(改造人間じゃなくロボットだからという言い訳はしたくない)。
サーフェスモデリングの練習でロボット頭部を作ってみる
サーフェスモデリングの練習でロボット頭部のモデリングを行ってみました。
デザイン自体はネットにあった人間用ヘルメットのマネです。正面図と側面図をキャンバスに貼りつけてから「位置合わせ」で大きさを調整、あとはお手本をなぞるようなかたちでサーフェスを定義しつなげていきました。何回も「計算できません」とFusion 360に怒られながらAdventurer 3で出力するところまでたどりつきました。
今はまだ、だめなときになぜだめなのかがわからないままにいろんなやりかたを試してみてうまくいく方法を探していくという感じです。