ホーム ブログ ページ 11

「ジョブローテーションで人を育てる」エクスペリエンスデザイン部 部長 南 弘紀 インタビュー

0

アピリッツにはゲーム開発の部門が五つあります。そのうちの一つ「エクスペリエンスデザイン部(以下、XD部)」はデザイナーが多く在籍する部署です。部長である南さんに、XD部の特色とどんなチームに育てたいかについて教えてもらいました。(2020年12月 取材)

南 弘紀 (みなみ こうき)
2017年 アピリッツ入社
休日は釣りにいったり海外ドラマや映画を見て過ごす。
海外ドラマはSF(ウエストワールド)からファンタジー(ゲーム・オブ・スローンズ)まで。
映画は恋愛(パンチドランク・ラブ)からアクション(マッドマックス)まで。
釣りはワカサギからシーバスまで。なんでもやります。

ゲーム会社からテレビ局、そして再びゲーム会社へ

ーー 南さんはアピリッツに入社してもうすぐ4年たちます。入社前はどのような仕事をされていましたか?

前職ではテレビ局で映像制作をしていました。それよりも前はちょっと複雑で、最初はコンシューマーゲームの会社でデザイナーとして数年働いたあと、ゲーム開発を目指している会社に縁があって転職しました。が、いろいろあって、そこではゲームが作れなかったんです。それで、テレビ局に入りました。リアルタイムCGとプログラムの知識のある人間が必要ってことだったんです。番組のCG映像を作成したり、バーチャルスタジオの作成をしたり。

ーー ゲーム業界からテレビ業界、そして再びゲーム業界に戻ったのですね。きっかけは何だったのでしょう?

自分がテレビ局で働いていた2014年頃から、スマートフォン向けゲームの会社がテレビ番組の一社提供のスポンサーとして登場しはじめたんです。しかも自分がゲーム業界にいた頃は聞いたことのない社名です。あー勢いがあるんだなと肌で感じました。それで、自分もスマホゲームに関わりたくてアピリッツに入りました。

デザイナーが多いチームでゲーム運営をするメリット

ーー XD部はどういうチームですか?

XD部全体で60人ほど所属しています。このうち50人近くはデザイナーですね。もともとXD部は社外のデザイン制作を受託するデザイン専門の組織でした。今はそれに加えて運営移管を担当し、ゲームの運営チームとしてプランナー、エンジニアも参加してもらっています。

また、去年からアニメ業界出身の人もXD部の仲間に加わりました。アニメをふくめたSDモーションの演出を一貫して作成し、ゲームに取り入れています。世の中の流れを考えても必要な要素です。

ーー ゲームの運営をXD部でやってみていかがですか?

デザイナーが一歩踏み込んだ仕事をできるようになりました。以前の仕事の流れだとプランナーからアートディレクターに依頼があって、その指示に沿って良いものを作りさえすれば良かったのですが、今は自分たちでKPIを分析し改善するところから関われますし、広告も自分たちで考えて提案します。

つまり、誰かと交渉したり、説明する必要ができてきます。「こっちのほうが良いから」だけじゃなく、相手にわかってもらうために「なぜこのデザインが良いのか?」その根拠を提示しながら伝える必要があります。なので、趣味趣向で提案するのではなく、論理的に説明できるデザイナーが育っています。

ーー 南さんはXD部の部長となって半年たちました。どんなチームを育てていきたいですか?

時代に見合った価値のある人材がいる組織にしたいです。

どの業種にしても同じですが、時代に関わらず価値が高く担保される唯一のスキルは「新しいことを学び続ける」スキルだと思います

そのために「ジョブローテーション」を取り入れてます。イラストレーターもモーションもやって、モーションをやってたメンバーをエフェクトチームに入れたり、クライアントエンジニアもサーバー側を触らせたり……。「新しい事を覚えるのが普通」という文化は育てたいですね。

苦労してでも「ジョブローテーション」をやったほうがいい理由

ーー ジョブローテーション、大変ではないですか?

みんな大変ですよ(笑)でも、僕は「やったほうがいい」と判断しています。

まず、向き不向きの問題です。そもそも若い人たちって「アピリッツでこれがやりたい」と入ってくるんです。目的や意欲があることは歓迎しますが、実は「本当に向いていること」への可能性を閉ざしてしまうリスクも生まれます。

なんでもそうでしょ? すべての業種に深みがあります。そしてそれは、やってみないとわからない。

ーー 「意外と向いてた」ってありますよね

はい。山をこえるまではしんどいけど、山をこえた人は新しい武器を手に入れることになるので「やってよかった」ってなるんですよね。

もちろん、知らない仕事に当たってモチベーションが下がることだってあります。しかし「モチベーションが上がらないから新しい事を覚えられない」となってしまうことは相当危険です。環境に左右されず「自分のキャリアのためにも新しいこと覚える」と真摯に取り組める人になってほしい。

ーー  環境に左右されない人は強いし、頼りにされますよね

はい。たとえばデザイナーからアートディレクターを目指す人は多いですが、アートディレクターはゲームの全リソースに責任を持つ仕事です。指示が出せない領域はあってはならないし、ベテランにだってきちんと指示を出さないといけない。

ゲームすべてのデザイン業務の指示が出来て、尖った武器を一つ持っている。そんなアートディレクターが存在したら、プロジェクトにとってこれ以上に頼れる存在はいない。

もちろん、管理側の立場からすると「この人はこれが得意だから」って、つい同じ仕事をアサインしたくなります。そのほうが正直使いやすいしラク。でも、本人にとって本当にいいことなのか? って長い目で考えると、本人のためにはならないと考えています。

だって、これから数年後に現れる若手は義務教育でプログラミングを勉強してるような子たちですよ? ひとつのことしかできない人が本当に今までの価値が担保できるのか? かなり疑わしい。

デザイナー出身の人間として、いまXD部にいる多くのデザイナーに将来のキャリアについてアドバイス出来ることがいろいろあります。そういうとき、僕はただ明るいだけの未来は提示しません。不況の波が一定の間隔で襲ってくることも知っていますし。一つのスキルに特化しすぎて辛酸を舐めている同世代もみています。多才かつ有能な若手だってどんどんあらわれる。

だから生き残れる人になってほしいです。そのためには、今の仕事に向き合い、技術を高め、次のステップに進むことが大切です。

深堀りできるひとは強い

ーー どんな人が伸びていますか? また、どんな人にXD部の仲間となってほしいですか?

ジョブローテであたえられた仕事に知識がない状態で入っても深堀りができる人ですね。勉強して、深堀りして、自分なりの解釈ができる人は伸びています。ときどき「こうあるべき」みたいな形を導き出すひとがいるんです。それって人から教えられてできるものじゃない。

技術や知識は、同業者や他業種の人とかかわることで得た情報を、自分で咀嚼することで、やっと身につけることができます。

今、エンジニアとデザイナーが一緒になってグラフィックデータの軽量化をゴリゴリやっていますが、そういった業務は互いに刺激しあえるので、深堀りができるチャンスだと思うし、両者ともそれをしっかり理解して進めることが出来ています。

何かを極限までやりつめてる人は、他の分野でも深堀りできます。掘りなれてるんでしょうね(笑)なんでもいいんです、研究でもスポーツでも。

ーー 南さん自身も部長になって変わったことはありますか?

経営が見えてきましたし、関わる人が増えて、アピリッツがどういう会社なのかがつかめてきました。契約や経理周りだって自分で勉強しないといけないですし、あたらしい領域を学ぶ訓練をしていなければ出来なかったことだなと思います。

誰しもが認める価値を身につけてほしい

ーー 心がけていることはどんなことでしょう?

なにをおいてもXD部のメンバーの市場価値を下げないこと。社内でも、世の中でも、市場価値が高いことは常に意識しています。デザイン業界には海外勢もいますし、低価格で良い絵を描く人もいっぱいいます。エンジニアリングに関してもプランニングに関しても、今と同じ仕事をしながら今の価値を保つことは難しいと感じています。

そんななかで、企業の中で活躍できる価値の高い人材とは? と考えると、開発や運営の状況をみて動ける人材はプロジェクトにとって有利ですよね。誰しもが認める価値だなと思います。

あとは、若いスタッフに対しては、早い段階で干渉しすぎないことも意識しています。「仕事で悩んでる」とよく聞きますが、業務において「悩む」ことは正しくない。「問題を解決する」ためにどういったアプローチをするか「考える」ことが正しい。そして本人が導き出した「考え」をもとに建設的な会話をおこない、スタッフの成長につなげたいと考えています。

関連記事:アピリッツのその他の役員インタビュー

デザイナーが要件定義に参画するメリット

0

こんにちは。デジタルビジネス部の内田です。
中途入社して1年、Webデザイナーとして様々なプロジェクトに関わって制作を行ってきましたが、最近では制作の前段階となる要件定義フェーズに加わることが増えてきました。

ディレクターやコンサルタントなどが担うことも多い要件定義フェーズですが、デザイナーがもっとビジネス的視点を持ってプロジェクトに関わることで、プロジェクトにもデザイナー自身にもメリットがたくさんあることを実感しました。
そこで、この記事ではデザイナーが要件定義に加わることで、どのようなメリットがあるのかをご紹介していきます!

そもそも要件定義とは?

Webサイトの制作やリニューアルを行う際、いきなり制作に入るのではなく、課題の整理やゴールの設定、現状や競合他社の分析・調査を行いつつ、ページの設計や構想をはっきりと定めます。

制作前にこのフェーズで構想を固めることで、のちの工程では決定した設計に沿ってフロント制作・システム開発に集中できたり、致命的な設計漏れなどを防いだりすることができます。

メリットその1:クライアントのビジネス課題を直接ヒアリングできる

メリットその1は、直接クライアントと会えるということです!
通常、Webデザイナーはユーザー視点に立ってデザインしがちな面があると思います。
また、クライアント視点の要件といったものはいくつか伝えられる程度で、顧客と会うことがあってもWeb担当者くらい…ということも少なくありません。

しかし、要件定義の段階だと、社長や取締役、営業担当者、実店舗のあるクライアントであれば実際にお客さんと会い、現場の実情をよく理解している人などなど…様々な方と会う機会があります。会議の場だけではなく、雑談や呟き程度でもその業界やクライアントの課題・目指したい方向性をより深く理解することができます。

このようにクライアントのニーズを直接伺って把握しておくことは、実際にプロジェクトの進行をスムーズにするだけでなく、デザイナーとしても制作の方向性が明確になったり思考の引き出しが増えたりするため大きなメリットになると実感しています。

メリットその2:定量的なデータを根拠に設計ができる

要件定義フェースでデータをもとにサイトの現状分析や問題提起、改善案の提示を行うことは、より効果的なサイト改善や制作に繋がります。私は部内のマーケティンググループに所属しているため、日頃からアナリストやコンサルタントの業務内容を聞いたり、アドバイスしあったりすることができます。そんな環境の助けもあって、クライアントにも「数字による根拠のある画面設計」を行えることはとても大きな強みだと思っています。

例えば、目的の売り上げやコンバージョン率を達成するために現状のデータを分析して、「このページでは◯%のユーザが離脱してボトルネックになっています!改善しましょう!」「そうですね!」とクライアントと示し合わせることで、なぜこの部分を改善する必要があるのかという明確な理由と双方の合意を経た制作を進めることができます。

また、デザイン制作段階でも、カラーや雰囲気はどういった感じにしたいかという要望だけでなく、「このページでは◯%のユーザが離脱しているからボタンのクリック率を◯%から◯%に上げたい」という課題が明確になっていることで、よりビジネス課題を解決できるデザインを提案することが可能になります。

メリットその3:制作経験があるからこそトラブルを防げる

プロジェクトの制作工程のみを担当している際、「この予算とスケジュールでは実装できないのですが…」「これはどう実装すれば…?」「この改修をしたいならエンジニアさんのアサインが必要だ!」と困った事態に陥ることがあります。

要件定義時に実現可能性が曖昧だと(これが起こるのは曖昧かどうかも判断できていない場合が多いですが)あとあと困ったことになるので、制作経験があるとこの辺りの判断が素早くできるのも強みだと思います。

まとめ

これまでのメリットをまとめると、実は自分が制作するときに揃えたいものを整理しているだけでは…?という気もしてきますが、デザイナーの視点と経験を要件定義に生かすことはクライアントや社内のメンバーなど、関わる人全てが障害なく役割に尽力して目的達成に近づく大きな手助けになると考えています!

【祝! 日本一】第12期 女流球聖位 荒木 愛 インタビュー【ビリヤードと仕事の話をします!】

0

エンパワーメントサービス部の荒木さんが日本アマチュアポケットビリヤード連盟主催の「第12期 女流球聖戦」を制し、タイトルを獲得しました! 日本一のポケットビリヤード選手がアピリッツにいる……! ということで、優勝記念インタビューです!

毎日ビリヤードの練習してます

―― まずは、アマチュアポケットビリヤード日本一、おめでとうございます!

ありがとうございます。

―― 荒木さんは毎日オフィスにいますよね。ビリヤードの練習は、いつ、どうやって……?

実は、ほぼ毎日やってます。仕事終わりにオフィスから歩いてすぐのところにある「ビリヤード相馬」というビリヤード場に通っているんです。原宿の駅前の老舗ビリヤード場です。私がアピリッツに入ったきっかけのひとつも「オフィスの立地が良いから(ビリヤード的に)」というものだったりしますし。練習方法は一人でやるよりも、お店の常連さんと一緒にプレイすることが多いです。

ただ、今年の4月頃は新型コロナウイルス感染症の影響でお店も閉まっていました。家で練習できる競技でもないので苦労しましたね。

―― そんななか優勝! ビリヤード歴はどのくらいですか?

13年です。ここまで大きな大会で勝ったのは今回が初めてでした。

JPA企業対抗戦に出たい

―― 「荒木さんはビリヤード強いよ」と噂には聞いていましたが、そんなにお強いとは

はい(笑) アピリッツ社内にもビリヤード部があります。 部員募集中です。初心者大歓迎ですし、私が教えます!

いつかアピリッツのみんなで”JPA企業対抗戦”に出てみたいんです。強い人ばかりのチームだと参加できないルールで、上級者、中級者、初級者の3人で一緒に頑張ります。(※ 現在はCOVID-19の対策のためビリヤード部はお休み中です)

―― 荒木さんと、あと2人で「チームアピリッツ」ということですね

はい。「武蔵野市役所」さんとかすごくお強いんですよ。企業対抗戦でも勝ちたい。

―― あの、その机の横にある黒い物体は……?

「キュー」です! 今日このあとビリヤード場に持っていきます!

机にたてかけてお仕事中。ビリヤードの試合では袖がひらひらした服装だとプレイできないので、シャープな服装の人が多いそうです。

―― ちょっとだけ見せてください!

職人さんに作ってもらったカスタムキューだそうです
「ゴエティアクロス」のワッペン。このポケットには「チョーク」も入ってます

クリエイターと並走する仕事

―― ずっとビリヤードの話を聞いていたいんですが、お仕事のことも知りたいです。エンパワーメントサービス部で荒木さんはどんな役割を担っていますか?

社外のプロジェクトで働いているアピリッツ社員のサポートです。契約周りや事務的なことはもちろん、1 on 1 の打ち合わせを重ねて、その人の仕事内容や、問題点をヒアリングして、一緒に考えていく役目です。

アドバイスというより一緒に考えて並走する役割です。「あなたは、どうしたい?」「こういう切り口はどう?」って。場合によっては、私が本人に変わってプロジェクトのご担当者さまと話し合うこともあります。

―― ES部のメンバーに「アピリッツの一員」と実感してもらうために大切なことは何でしょう?

そこはいつも気にかかっています。まずは「安心して働ける環境をつくる」ことを心がけています。誰だって最初は「外部のプロジェクトに一人で参加する」って不安なことです。なので、心細さが和らぐように連絡や面談は丁寧に重ねますし、外部との面談にも同席します。そして「本人の意志を尊重」して動いています。

ただ、みなさん不安なのは最初だけですね。やがてプロジェクト内で評価されて自信をつけていきます。

また、大抵の場合は大手ゲーム会社さまのプロジェクトです。外部スタッフを受け入れることに慣れている会社さまが多いので、そういった意味でもスムーズに進みます。誰もが知っているIPを取り扱ったり、大規模プロジェクトに参加できたり。そういった意味でも面白いはずです。(あと社員食堂が美味しかったり……)

ゲーム業界で働きたいクリエイターの方はぜひ「アピリッツクリエイターズ」をチェックしてください!

―― 外部の会社さまからアピリッツの社員の評価はいかがですか?

評価は高いですよ! みなさんアピリッツの正社員で、熱心なクリエイターで、とても真面目なので。

―― 会社で働いて、社外でもひたすらビリヤードで戦って……両立ってできるものなのですね

できますできます。ちなみにビリヤード界は老若男女いらっしゃいますし、職業もバラバラです。エンジニアさんも多いので、みなさんぜひアピリッツに来てほしいですね。ビリヤード場も近いですし(笑)

女性でもひょいっと背負えるサイズ

―― さいごに、今後の目標を教えて下さい

ビリヤードは「今回はラッキーだった」と思われないように、そしてアピリッツではみんなが仕事しやすいように立ち回りたいです。

―― ありがとうございました!

未経験でIT業界への転職ってどんな感じ? DMM WEBCAMP(DMM ウェブキャンプ)出身のエンジニアに本音で語ってもらいました

0

IT業界未経験からプログラミングスクールを経てアピリッツに転職したみなさんにお話を聞くと、みなさん覚悟を持って異業種から挑戦しているのだなと感じます。今回はDMM WEBCAMP 出身の3人のエンジニアに、学習や転職活動のこと、新型コロナウイルス感染症の影響がどんなものであったか、そしてアピリッツに入ってからの様子を教えてもらいました。

【お知らせ】プログラミングスクール出身者のエンジニア積極採用キャンペーン実施中!

―― IT業界を志したキッカケを教えてください

ただ、日本を長期間はなれて働くことが徐々に自分の人生と合わなくなって退職しました。少し空白期間を置いたのち、「技術を高めていく仕事がしたい」と思ってIT業界を志しました。もともと興味がありましたし、年齢も20代後半だったので、キャリアチェンジのラストチャンスを逃して後悔をしたくないという思いもありました。

新奥:私はもともと海運会社で航海士を5年やっていました。「人が経験していないことを経験したい!」と思ったからです。実際、言語も文化もちがうクルー達と大海原を航海した5年間は今の私をかたちづくる人生の糧となっています。

柴田:私は「ものづくり」により深く関わりたかったからです。前職は広告代理店に勤めていました。そこでWebサイトの文章作成に関わったときに達成感があって楽しかったので、エンジニアを志しました。多くの人に使ってもらえるサービスをイチから作りたいです。

角:学生時代からパソコンを触るのが好きでしたが、深く学ぶチャンスがなくてIT業界とは縁遠いなあと思っていました。でも、プログラミングスクールの存在を知って、一度挑戦してみることにしたんです。愛知から引っ越してスクールに通いました。……そうこうしているうちに、コロナの波がやってきて。

―― ちょうどみなさんがスクールに通っていた頃に、新型コロナウイルス感染症拡大の問題が大きく取り上げられるようになりました。やはり影響は大きかったのですね

角:とにかく就職活動がどうなるのか本当に不安でした。愛知からはるばる引っ越してきたのに、タイミングを間違えたかも? って。ただ、仲間がいたので励みになりました。今でも一緒に勉強したり、飲みに行きます。

新奥:私も仲間の存在は大きかったですね。本当ならDMM WEBCAMPのおしゃれな教室で勉強するはずだったのに、コロナ禍の影響で完全在宅で学習することになったんです。幸い、オンライン授業の体制がすぐに整いましたし、仲間ともオンラインでめちゃくちゃ密にコミュニケーションをとりました。

柴田:チーム開発はやっぱり楽しかったですよね。達成感がありました。不安はみんな抱えていましたよ。求人数も減っていくなかで、未経験エンジニアが本当に転職できるのか? って。でも周りのみんなも真剣に頑張っていましたし、お互い励まし合いました。

ES部 角さん

―― 未経験からエンジニアになるための勉強は、だいたいみなさん「毎日8時間くらい」とおっしゃいます

柴田:そうですね。一週間のうち一日は休息・自由日にして、それ以外の日は平均して一日に8時間は勉強していました。期間は、スクールに入って、アピリッツに入社するまでの8ヶ月です。

角:僕も8時間。ただ、スクールに入るまではどんな勉強をしたらいいのか謎で「やる気が出たら一時間やる」……といった感じでした。スクールに入ってからはコツや目処がついたので、勉強が楽しくなりました。期間は4ヶ月くらいです。

新奥:勉強だけに打ち込む環境を作ったあとは、毎日8時間、ほぼ休みなく続けていました。そんな生活を半年ほど続けていたので、アピリッツに入社を決めてから3日間はYou Tubeとか見ながらひたすらダラダラしました。

―― 就職活動はいかがでしたか?

柴田:とある企業さまから「あなたを採用したら企業にどんな利益がありますか?」とズバッと尋ねられて、その場できちんと答えられず悔しかったです。ただ、あらためて自問自答する良いキッカケをいただいたと思います。

新奥:最初に面接を受けた会社で内定をいただけたんです。採用の連絡をもらったときは家で一人で叫びました。ああ自分の頑張りが認められたんだ、って。アピリッツの面接では将来のビジョンを深堀りされて、5年、10年後のキャリア像をきかれるのはもちろん、「20年・30年後はどうなっていたい?」なんて部長から訊かれたり。びっくりしましたね。

角:面接では「嘘はやめよう」と真摯にのぞみました。

――アピリッツに決めた理由を教えて下さい

角:今まで習ってきたRuby on Rails、AWSといった内容を手広くやっている印象だったのと、会社と一緒に自分も成長できると感じたからです。

ES部 柴田さん

柴田:あと、技術力や情報発信力の高さも魅力でしたね。面接での話しやすさも大きかったです。私の色んな面を掘り下げてもらえましたし、キャリア展望のこともふくめ、腹を割って本音で話せました。

新奥:専門性の高いエンジニアがいるのは魅力的でした。自社のエンジニアの成長を重視している会社だとも感じました。ここなら、キャリアの幅が広がりそうだなと考えました。

―― 実際に働き始めていかがですか? 今までとのギャップはありましたか?

角:デスクワークってこんなに体が疲れないんだなと驚きました。仕事は、先輩のフォローがあるのでなんとかやっていけているなと思います。エンジニアって優しい人が多いなと……。

新奥:そうですね、実際に入ると、いろいろ安心しました。エンジニアYouTuberの動画を見ていると「モダンな技術を扱えないと未経験からのエンジニア就職は無理、入社してもすぐ落ちこぼれてクビになります!」ってめっちゃくちゃ煽られるんですけど、そんなことなかったなって思いました。もちろん勉強は必要ですし、年下や同い年のエンジニアが私の先輩です。日々食らいつくように働いています。

あと、業務指示への返答は「Yes, Sir!」が基本だった元船乗りの立場からすると、Slackのやりとりにびっくりしますね。上司にスタンプ一個で返事したり。ラフで良いなあと思いますね。

柴田:未経験でもすぐに開発現場に入れる環境があったので良かったです。あと定時退社の方も少なくないですし、ホワイトだなと思います。経験を積んで、将来はプロジェクトマネージャーやリーダー的存在になりたいです。そして多くのひとに使ってもらえるサービスを作りたいですね。

―― 最後に、スクール生のみなさんにメッセージをお願いします

柴田:勉強でも、転職でも、すぐに結果が出ないこともあるはずです。でも自暴自棄になったりせず、気持ちを整理しながら根気強く頑張ってほしいです。リフレッシュも大切ですよ!

新奥:未経験からエンジニアを目指すと、いろんな情報に出合って混乱するかもしれません。「コロナで未経験からのエンジニア就職は無理!25歳以上は諦めろ」とか、反対に「未経験からのエンジニア就職はこれさえ抑えれば楽勝」という有料NOTEが売ってたり。そんなカオスに惑わされず、一歩一歩確実に進んでほしいです。

私も、日々の業務に全力で取り組んで「スタートが遅くともそこからの努力次第で十分に活躍できる」ということを自身のエンジニア人生をかけて証明していきたいです。

MS部 新奥さん

角:やめないかぎりは誰でもできるようになるはずです。ですから、周りばかり気にせず、カオスな情報にまどわされず、自分のペースでがんばってください。僕もいつかはできるようになると自分を信じてがんばります。

動的サイト向けのテンプレートを作成する時に押さえておきたいポイント

0

デジタルビジネス部所属Webデザイナーの今井です。
動的サイトのデザインというのは静的サイトに比べると変化が多く、その分考慮すべきことがたくさんあります。
今回はWebディレクターやデザイナー向けに手戻りの少ないテンプレートを作成するポイントをご紹介します。

文字数の増減による変化

商品名やニュース記事のタイトルなど、文字数が一定ではない情報は動的サイトには数多く存在します。
ECサイトの一覧では画像の下にタイトルと金額が、ニュースサイトでは画像の下に記事タイトルや日付等が入るのはよくあるパターンですが、このタイトルがすべて同じテキストであるというのもワイヤーフレームやデザインではよくあるパターンです。
しかし実際にはタイトルはデザインの想定通りにはまらないことも少なくありません。
タイトルを2行で想定したデザインの場合、タイトルが1行分しかなかったらその下の要素は上につまる?それとも位置は変わらない?
デザインにあるより長いタイトルもそのまま全部表示する?それとも2行を超える場合は「…」と省略する?
タイトルの表示方法についてはシステムの仕様はあまり深く関わらないため組み込みで戻ってくることは少ないです。
しかし見栄えに関わるため、実態に近い状態を想定してUIを考慮して決めておくことで実装後の修正を防ぐことができます。

要素の増減による変化

文字数の長短以外にも、要素そのものが増えたり減ったりすることもよくあるケースです。
閲覧したアイテムを他のページで一覧表示する場合、1列5件まで表示できるとして、6件以上あったらどうなるのか。
最大5件までしか表示しない?それとも2列目もある?あるいはスライダーが起動する?
これはシステム要件とも関わるので、事前に確認しておきたいポイントです。

バリエーションの網羅性

ECサイトの場合他にもよくある変化として、購入可能、完売、予約、再入荷待ちなどのステータスがあげられます。
また、新着やおすすめなどのタグデータを持つものもあるし、セール価格を表示することもあります。
ワイヤーフレームでは考えられるすべてのパターンを網羅し、必要なだけデザインのバリエーションを作成しておくことで、コーディング時に必要なパーツを網羅することができ、組み込み時のパーツ不足による手戻りを防ぐことができます。

データの表示方法

動的サイトでは多くの項目がデータベースの値を出力することで表示されています。
ここで気をつけたいのは、データベースから出力されるデータにはタグを挿入できない、ということです(元々のデータにタグが入っている場合は別ですが)。
例えば商品名や記事タイトルのような要素はデータベースでは1つのデータとして格納されていて、テキストの一部だけ太字にしたくてもできないし、読みやすいように途中に改行を入れることもできません。
日時表示をする際に、日付と時間が1つのデータとして扱われていたら、時間だけ小さく表示する、ということはできません。しかし、日付と時間がそれぞれ別のデータとして存在していたら、時間だけ小さく表示することができます。
データベースにどのようにデータが格納されているかはデザインに落とし込む際に大事なポイントです。

ボタンクリックによる挙動

Webページには多くのボタンやリンクが存在します。
クリックして遷移する、フォームが送信される、jsによるインタラクションが発生するというのが予想される挙動ですが、動的サイトのコーディングをする場合ページ遷移を実装するかどうかは場合によるため、基本的に実装しておくべき挙動がある場合はコーダーに挙動に関する情報を共有しましょう。
特にモーダルやtoggleのような要素は、テンプレートをコーディングするコーダーが起動するところまで実装するのか、システムに組み込む際にエンジニアが実装するのか線引きが曖昧な部分があるため、コーディング時に何を実装すべきかは組み込むを行う開発者と協議して明確にしておいた方がよいでしょう。

toggleする要素の変化

メニューボタンをクリックすると折り畳まれていたメニューがtoggle展開する。よくある仕組みです。
また、最初の数行だけ表示して「もっと見る」を押すと残りがtoggle展開で表示されるというケースもよくあります。
一度展開した要素を再び閉じることができるのか、閉じることができるなら「もっと見る」のテキストが「閉じる」に変化するのか。
よくあるがゆえに「普通こうなるだろう」という思い込みで挙動に関する情報が足りないことがあります。
「もっと見る」は「閉じる」に変わるのが普通かもしれないし、「もっと見る」を開いた後は閉じられなくなるのが普通かもしれません。
当たり前の挙動をする場合もコメントやデザインで明示しておくことで、当たり前を共有することができます。

モーダルの挙動

メッセージや拡大画像、情報を表示する際によく使われるモーダル。
情報やフォームを表示する場合、モーダルで表示されるコンテンツがブラウザの高さにおさまらない場合、ブラウザ全体がスクロールするのか、モーダル内でスクロールするのかというのがまず大きなポイントです。
モーダル内でスクロールする場合、見出しや下部にあるボタンは固定されるのか、固定される場合、それぞれどの程度の領域が必要になるのかをデザインの段階までに決めておかないと、コーディング時に思ったより固定される領域が大きくてコンテンツが見づらい、ということが起こります。
また、モーダルは基本的に閉じる手段が必要です。
×ボタンや閉じるボタンが設置されているか、すべてのモーダルで同じ位置にあるか、あるいはモーダル内から別ページに遷移させるために閉じられないようにするのかを、システムの仕様も踏まえて決めておく必要があります。
画面全体を半透明のオーバーレイで覆っている場合、オーバーレイをクリックして閉じるかどうかも必要な情報です。

0件/エラーパターン

一覧で0件だった場合、フォームの入力エラーなどは必要ながらもつい忘れられがちな要素です。
特にフォームのエラーはシステム的に出力されるので、デザインを作成する際にはすべてのフォームで統一されたデザインにしておく必要があります。
フォームが存在するすべての画面にエラーデザインを作ることは時間もコストもかかりすぎるため、通常はピックアップされた2〜3画面にエラーパターンを追加する程度になりますが、フォームはエラーがでることを念頭にデザインを作成すると良いでしょう。

最後に

動的サイトで変化するポイントは他にもいろいろありますが、これまで私が経験した多くのWebサイトに当てはまるポイントをご紹介しました。
どこがどう変化するか、というのは想像力も必要です。上記のポイントを踏まえて、自分が作成しようとしているワイヤーフレームやデザインが実際に動くとどうなるかを想像してみてください。今のワイヤーフレームやデザインでは足りないパーツや、必要なパターンが見えてくるかもしれません。

機械学習によるアイコン画像生成のこころみ (実践編)

0

実践編では、機械学習の手法によるアイコン画像の生成について書いていきます。

前回の下調べ編では CycleGAN でのスタイル変換によるアイコン画像生成の先例を見ていきました。今回はその再現を実践していきます。

実践にあたっては以下を順に見ていきます。

  1. 実装
  2. データセット
  3. 実行環境

1.実装

実装は前述のとおり junyanz/pytorch-CycleGAN-and-pix2pix を利用したとのことなのでこれを利用します。データセットを所定のディレクトリに配置し学習します。

おそらく以下のような実行方法になります。

# 32x32 のデータセットを配置し、そのデータセットでの学習 (4つの GPU があるものとする)
python train.py --dataroot ./datasets/iconify32x32 --name iconify_cyclegan --model cycle_gan --gpu_ids 0,1,2,3 --batch_size 16
# 64x64 のデータセットでのファインチューニング
python train.py --dataroot ./datasets/iconify64x64 --name iconify_cyclegan --model cycle_gan --gpu_ids 0,1,2,3 --batch_size 16 --continue_train
# 128x128
python train.py --dataroot ./datasets/iconify128x128 --name iconify_cyclegan --model cycle_gan --gpu_ids 0,1,2,3 --batch_size 16 --continue_train
# 256x256
python train.py --dataroot ./datasets/iconify256x256 --name iconify_cyclegan --model cycle_gan --gpu_ids 0,1,2,3 --batch_size 16 --continue_train

まず最初に解像度の低い画像のデータセットで学習し、だんだん解像度を上げていきます。この実装では --continue_train フラグを指定することで、モデルをファインチューニングできるので、2回目以降の解像度ではファインチューニングとして実行していきます。

2.データセット

ロゴ画像については、400×400 のサイズの画像をリサイズしていけばよさそうです。一方で実写の物体の画像を用意するのはひと手間かかる予感がします。

pycocotools を使って COCO のアノテーション情報をもとに加工していきます。ひとまずどんなライブラリかコンソールで確認していきます。

>>> from pycocotools.coco import COCO
>>>
>>> annotation_path = 'datasets/coco/annotations/instances_train2017.json'
>>> coco = COCO(annotation_path)
loading annotations into memory...
Done (t=23.60s)
creating index...
index created!

画像のリソースや、そのアノテーション情報にアクセスできます。

>>> img_id = coco.getImgIds()[0]
>>> img_id
391895
>>> img = coco.loadImgs(img_id)
>>> img
[{'license': 3, 'file_name': '000000391895.jpg', 'coco_url': 'http://images.cocodataset.org/train2017/000000391895.jpg', 'height': 360, 'width': 640, 'date_captured': '2013-11-14 11:18:45', 'flickr_url': 'http://farm9.staticflickr.com/8186/8119368305_4e622c8349_z.jpg', 'id': 391895}]

画像のリソースの情報にアクセスできます。

なお、ここでの license の項目は画像のライセンスをあらわす定数のようです。完全に脱線してしまいますが、アノテーションファイルの JSON から jq .licenses instances_train2017.json などとしてライセンスの情報をみてみます。

[
  {
    "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/",
    "id": 1,
    "name": "Attribution-NonCommercial-ShareAlike License"
  },
  {
    "url": "http://creativecommons.org/licenses/by-nc/2.0/",
    "id": 2,
    "name": "Attribution-NonCommercial License"
  },
  {
    "url": "http://creativecommons.org/licenses/by-nc-nd/2.0/",
    "id": 3,
    "name": "Attribution-NonCommercial-NoDerivs License"
  },
  {
    "url": "http://creativecommons.org/licenses/by/2.0/",
    "id": 4,
    "name": "Attribution License"
  },
  {
    "url": "http://creativecommons.org/licenses/by-sa/2.0/",
    "id": 5,
    "name": "Attribution-ShareAlike License"
  },
  {
    "url": "http://creativecommons.org/licenses/by-nd/2.0/",
    "id": 6,
    "name": "Attribution-NoDerivs License"
  },
  {
    "url": "http://flickr.com/commons/usage/",
    "id": 7,
    "name": "No known copyright restrictions"
  },
  {
    "url": "http://www.usa.gov/copyright.shtml",
    "id": 8,
    "name": "United States Government Work"
  }
]

上記の画像のリソースの情報は CC BY-NC-ND なので、会社のブログで画像を切ったり貼ったりするのには適さなそうです。CC BY 2.0 の 4 からランダムに選んでみます。

>>> ids = coco.getImgIds()
>>> imgs = coco.loadImgs(ids)
>>> import random
>>> img = random.choice([i for i in imgs if i['license'] == 4])
>>> img
{'license': 4, 'file_name': '000000226571.jpg', 'coco_url': 'http://images.cocodataset.org/train2017/000000226571.jpg', 'height': 426, 'width': 640, 'date_captured': '2013-11-18 21:53:31', 'flickr_url': 'http://farm4.staticflickr.com/3037/3054252115_dca3690eb8_z.jpg', 'id': 226571}
000000226571.jpg

4 of 4 Two Equestrian Horse Riders on Morro Strand State B… | Flickr

馬にのった人物の画像でした。

補足:一応クレジット表示のためにもとの画像の URL もさがしておきます。Find photo URL by filename of jpg によるとファイル名から探せるようなのでさがします。今回は http://flickr.com/photo.gne?id=3054252115 → https://www.flickr.com/photos/mikebaird/3054252115/ で探せました。以上脱線終わりです。

つづいてアノテーションも見てみます。

>>> ann_ids = coco.getAnnIds(imgIds=[img['id']])
>>> ann_ids
[54013, 54104, 185138, 209986, 1376036]
>>> anns = coco.loadAnns(ann_ids)
>>> ann = anns[2]
>>> ann
{'segmentation': [[345.95, 149.26, 345.95, 152.32, 345.95, 155.0, 340.98, 156.91, 330.65, 163.03, 332.18, 164.57, 339.06, 165.33, 334.47, 176.43, 326.82, 187.52, 325.29, 193.64, 326.44, 208.18, 325.29, 223.86, 325.29, 237.64, 342.12, 263.27, 352.07, 272.02, 352.84, 294.97, 359.72, 322.52, 359.72, 332.08, 364.69, 329.79, 365.08, 326.34, 368.14, 314.1, 371.58, 314.48, 372.73, 321.75, 373.88, 327.87, 375.02, 330.93, 382.29, 329.79, 383.06, 329.4, 383.44, 329.4, 384.97, 325.2, 381.91, 324.81, 375.79, 319.07, 373.11, 312.95, 370.43, 303.39, 370.05, 299.18, 370.43, 289.62, 370.43, 267.04, 364.31, 253.27, 358.96, 238.02, 364.31, 233.43, 363.93, 222.72, 371.58, 221.19, 384.59, 220.8, 390.71, 220.04, 389.18, 216.21, 387.65, 212.39, 386.5, 210.09, 376.94, 211.62, 363.93, 212.39, 362.4, 192.88, 366.99, 182.21, 364.31, 182.21, 360.49, 181.83, 356.66, 179.92, 356.66, 178.77, 361.25, 178.77, 362.78, 175.33, 363.55, 173.03, 366.23, 172.65, 367.37, 171.5, 366.61, 166.91, 367.37, 163.47, 368.14, 161.94, 375.02, 163.09, 381.15, 163.09, 380.38, 160.41, 367.76, 155.05, 365.08, 146.25, 352.84, 145.11, 344.42, 147.4]], 'area': 5287.617649999996, 'iscrowd': 0, 'image_id': 226571, 'bbox': [325.29, 145.11, 65.42, 186.97], 'category_id': 1, 'id': 185138}

これだけだとよくわからないのでマスクに変換して形状を見てみます。

>>> mask = coco.annToMask(ann)
>>> mask
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
>>> import numpy as np
>>> from PIL import Image
>>> masking = Image.fromarray(mask * 255) # mask は 0, 1 の numpy.ndarray になっているので 1 の部分を白くするために 255 をブロードキャストします
>>> masking.save('masking.jpg')
masking

このアノテーションは上の画像の人間の部分のようです。

これをつかって切り抜いてみます。

>>> from skimage import io
>>> image = io.imread(img['coco_url'])
>>> image[np.where(mask == 0)] = 255 # マスクで 0 になっている部分 (背景部分) を白くしてしまう
>>> Image.fromarray(image).save('masked-image.jpg')
masked-image

対象領域だけにしぼってみます。すこし煩雑になってきたのでメソッドを定義します。

>>> def object_rect_indices(mask):
...     '''アノテーションのマスクからオブジェクトの矩形領域の両端 (top, bottom, left, right) を返す
...     '''
...     ys, xs, *_ = np.where(mask == 1) # mask は2次元配列の想定
...     top = ys.min()
...     bottom = ys.max()
...     left = xs.min()
...     right = xs.max()
...     return (top, bottom, left, right)
...
>>> def clip_image_margin(image, mask):
...     '''画像の余白を削って返す
...     '''
...     top, bottom, left, right = object_rect_indices(mask)
...     return image[top:bottom, left:right]
...
>>> clipped = clip_image_margin(image, mask)
>>> Image.fromarray(clipped).save('clipped.jpg')
clipped

よさそうです。正方形にしてしまいます。

>>> def to_square(image):
...     '''画像の ndarray を、長辺にあわせて正方形に余白を追加した ndarray を返す
...     '''
...     h, w, *_ = image.shape
...     pad_width = [(0, 0)] * image.ndim # 2値画像なら二次元分、RGB 画像なら三次元分
...     if h > w:
...         # 縦長なので横方向にパディングする
...         size = h
...         padding = size - w
...         before = padding // 2
...         after = padding - before
...         pad_width[1] = (before, after)
...     else:
...         # 横長なので縦方向にパディングする
...         size = w
...         padding = size - h
...         before = padding // 2
...         after = padding - before
...         pad_width[0] = (before, after)
...     padded = np.pad(image, pad_width, constant_values=255) # 余白は白で埋める
...     return padded
...
>>> square_image = to_square(clipped)
>>> Image.fromarray(square_image).save('square-image.jpg')
square-image

こういう画像が用意できたらあとはリサイズしていけばよさそうです。


今回は以下のようなスクリプトにまとめて小さい画像を排除しつつ切り出しとリサイズを行いました。

import numpy as np
from PIL import Image
from pathlib import Path
from pycocotools.coco import COCO

# instances_train2017.json でのアノテーションでは、セグメントのピクセルサイズの
# 中央値が 1696 くらいなので、ひとまず 1500px あれば小さいとはみなさないことにする。
SMALL_IMAGE_PIXEL_THRESHOLD = 1500

# データセット用にリサイズするサイズ
SIZE_32x32 = (32, 32)
SIZE_64x64 = (64, 64)
SIZE_128x128 = (128, 128)
SIZE_256x256 = (256, 256)

def is_satisfied_object_size(mask, min_threshold=SMALL_IMAGE_PIXEL_THRESHOLD):
    '''アノテーションのマスクの ndarray から対象セグメントのサイズが訓練に使えるサイズかどうかを判断して返す
    '''
    return np.size(mask[mask == 1]) >= min_threshold

def extract_object(image, mask):
    '''マスク対象の画像 image の ndarray と、mask の ndarray で、対象のセグメント部分以外を白く塗り潰した ndarray を返す
    '''
    extracted = image.copy()
    extracted[np.where(mask == 0)] = 255 # セグメントのオブジェクト以外の部分を白くする
    return extracted

def object_rect_indices(mask):
    '''アノテーションのマスクからオブジェクトの矩形領域の両端 (top, bottom, left, right) を返す
    '''
    ys, xs, *_ = np.where(mask == 1) # mask は2次元配列の想定
    top = ys.min()
    bottom = ys.max()
    left = xs.min()
    right = xs.max()
    return (top, bottom, left, right)

def clip_image_margin(image, mask):
    '''画像の余白を削って返す
    '''
    top, bottom, left, right = object_rect_indices(mask)
    return image[top:bottom, left:right]

def to_square(image):
    '''画像の ndarray を、長辺にあわせて正方形に余白を追加した ndarray を返す
    '''
    h, w, *_ = image.shape
    pad_width = [(0, 0)] * image.ndim # 2値画像なら二次元分、RGB 画像なら三次元分
    if h > w:
        # 縦長なので横方向にパディングする
        size = h
        padding = size - w
        before = padding // 2
        after = padding - before
        pad_width[1] = (before, after)
    else:
        # 横長なので縦方向にパディングする
        size = w
        padding = size - h
        before = padding // 2
        after = padding - before
        pad_width[0] = (before, after)
    padded = np.pad(image, pad_width, constant_values=255) # 余白は白で埋める
    return padded

def extract_square_object_image(image, mask):
    '''正方形にセグメント対象を切り抜いた ndarray を返す
    '''
    extracted = extract_object(image, mask)
    clipped = clip_image_margin(extracted, mask)
    square_image = to_square(clipped)
    return square_image

def image_file_name_from_annotation(ann):
    '''アノテーションから画像ファイル名を返す
    '''
    return '%012d.jpg' % ann['image_id']

def load_image(ann, image_src_dir_path):
    '''アノテーションからアノテーション対象のオリジナル画像を返す
    '''
    # image は image_src_dir_path にアノテーション対象の画像があるのものとして読み込む (なければそのまま例外スロー)
    file_name = image_file_name_from_annotation(ann)
    src = Path(image_src_dir_path) / file_name
    image = np.array(Image.open(str(src)))
    return image

def make_datasets():
    '''写真画像のデータセットをつくる

    対象のみを切り出し白背景にして、32x32, 64x64, 128x128, 256x256 のサイズにリサイズした画像を作る。

    datasets/coco/annotations/instances_train2017.json のアノテーション情報と画像をもとに、以下のサイズごとのディレクリにリサイズして画像を置く

    - datasets/images/photo/32x32
    - datasets/images/photo/64x64
    - datasets/images/photo/128x128
    - datasets/images/photo/256x256

    各サイズごとに 447921 とか画像が作られるので時間がかかる (適当なところで break したほうがいいかも)
    '''

    # photo_image.py
    current_file_path = Path(__file__).resolve()

    # coco の情報
    coco_base_path = current_file_path.parent.joinpath('datasets/coco')
    coco_annotation_path = coco_base_path / 'annotations/instances_train2017.json'
    coco_image_path = coco_base_path / 'train2017'

    # 出力先
    image_datasets_path = current_file_path.parent.joinpath('datasets/images')
    image_datasets_path.mkdir(parents=True, exist_ok=True)

    # 写真画像の出力先
    photo_image_dataset_base_path = image_datasets_path / 'photo'
    photo_image_dataset_base_path.mkdir(parents=True, exist_ok=True)

    # 4サイズつくる
    sizes = [SIZE_32x32, SIZE_64x64, SIZE_128x128, SIZE_256x256]
    dests = ['32x32', '64x64', '128x128', '256x256']
    # ディレクトリ掘っておく
    for directory in dests:
        path = photo_image_dataset_base_path / directory
        path.mkdir(parents=True, exist_ok=True)

    size_with_dst_pairs = list(zip(sizes, dests))

    # coco のアノテーションと画像ファイルからリサイズしたデータセット画像作成
    coco = COCO(str(coco_annotation_path))
    ann_ids = coco.getAnnIds()
    for ann in coco.loadAnns(ann_ids):
        ann_id = ann['id']
        print(f'process {ann_id}')
        mask = coco.annToMask(ann)
        if not is_satisfied_object_size(mask):
            # サイズが小さければスキップ
            print('skipped.')
            continue
        image = load_image(ann, coco_image_path)
        square_image = extract_square_object_image(image, mask)
        object_image_file_name = f'{ann_id}.jpg'
        for size, dirname in size_with_dst_pairs:
            dest = photo_image_dataset_base_path.joinpath(dirname, object_image_file_name)
            resized = Image.fromarray(square_image).resize(size)
            resized.save(dest)
            print(f'save {dest}')

        print('done.')

if __name__ == '__main__':
    make_datasets()

3.実行環境

AWS で実行します。
前出の実装のリポジトリに colab (colaboratory) での実行例が用意されています (CycleGAN.ipynb)。馬とシマウマのデータセットで学習を試してみたところ半日で終わらず、200 epoch のうち数 epoch しか進んでいません。与えられたデータを全部使った学習を200回まわすようになっていますが、そのうちの数回しかまわせていませんでした。おそらく colab では事前に学習済みのデータ (pretrained model) を使って生成を試すのを想定していそうです。これよりデータ量の多い今回の再現も colab では手にあまります。なので AWS を利用します。

機械学習の用途なので NVIDIA Deep Learning AMI の AMI を利用してみます。Docker で実行することも考えましたが、本題以外の部分でハマりたくないため、EC2 でそのまま実行していきました。事前に作成して S3 にアップしておいたデータセットを持ってくるために awscli や、必要なライブラリ (libffi-dev などが必要になるかもしれません) を導入します。

以下のサイズで動作を見ていきます。

  • t2.micro
    • S3 のリソースにアクセスできるかなど雑多な準備・確認用
  • g4dn.xlarge (T4 x 1GPU)
    • GPU を使って実行できるかどうかの確認用 (colab でも同程度の GPU なので期待はしない)
  • g4dn.12xlarge (T4 x 4GPU)
    • 複数 GPU を使えるかどうかの確認用 (あわよくば現実的な実行時間で済むかかもくらいに期待)
  • p3.16xlarge (V100 x 8GPU)
    • 強い GPU で実行した場合にどれくらいの実行時間になりそうか確認する用

p3.16xlarge (8GPU を利用し、バッチサイズが 36 になるよう指定して実行、イテレーションは 5000) で動作確認して 1 epoch どれくらいかかるか見てみたところ、およそ120秒となりました。すなわち 200 epoch 完了するのに数時間かかります。ここに3回ファインチューニングを重ねるためさらに時間がかかります。今回の再現がこのコストに見合うかというと微妙なところです。ひとさまがすでに論文として仕上げているものを再現するためだけにこれほどのコストをかけてよいものか、また再現する価値があったとしてその先はどうするのか、少し考える必要があるように思います。

実際のところ、この数時間ぶん程度の実行コストは機械学習のタスクとしては現実的な範囲に見えます。しかし、ここからさらに実用的なものを目指したり発展させていくなら検証をかさねることになります。この先進むには当初の動機が軽すぎるためコストをかける説得力がありません。そういうわけで、ここで一旦再現を中断することにしました。低コストで効率的に実行する方法を探ったり、計画を立てるなどして説得力を増す必要があります。

実践編 まとめと感想

中途半端な状態で終わってしまいましたが、論文に書かれた内容を追って、そこに込められた工夫を知れたのはよかったです。理論を整理して実際に動かし検証をやりきるのにたくさんのリソース (人的にも計算資源的にも) がかかることを考えると、論文をまとめることのすごさを感じました。今度はもうすこし具体的な道筋を考えるか、小さくはじめられるこころみでリベンジしていきたいです。

機械学習によるアイコン画像生成のこころみ (下調べ編)

0

何かと必要とされるアイコン画像を、人手をかけず気軽に作ることができたらうれしい! そんな夢をかなえたく、機械学習によるアイコン画像生成をこころみました。

今回こころみたこと

ここでは先行事例(くわしくは後述します)にならい、CycleGAN でのアイコン画像生成をこころみます。この下調べ編では仕組みについて見ていき、続く 実践編で具体的に動かしていきます。

すすめていくと、気軽な生成のためには気軽ではない準備が必要でした。またコストの面でも “機械学習で発生するものとしては現実的な範囲、ただし気軽に試すにはためらう程度” のリソースが必要になりました。今回のこころみでは気軽な範囲にとどめ、最後の一歩手前までを実践していきます。

動機

今回アイコン画像の生成をこころみた動機は主に以下の2点でした。

  1. 機械学習での生成をためしたい
  2. オリジナリティのあるアイコン画像を気軽に手に入れたい

1.機械学習での生成をためしたい

過去の案件で何かを予測したり識別したりするような課題を扱ったことはありますが、何かを生成するような課題については経験が少ないため、生成に関する知見を増やしたいです。

2.オリジナリティのあるアイコン画像を気軽に手に入れたい

システム開発では何かとアイコン画像の出番があります。しかも、対象のシステムに特化した “こういうアイコン画像が欲しいです” となることがたびたびあります。また、いろいろなアイコン画像を試してみたいという要望もしばしばあります。

特化したアイコンについては、様々なテイストのアイコンセットやニッチな領域に特化したアイコンが販売されているのでそれを利用する手もあります。とはいえピンポイントなものを探す手間はかかりそうです。

いろいろなアイコンを試してみたいという要望については、なるべくデザイナーの手を煩わすことなくアイコン画像の候補を用意したいところです。デザイナーの手にかかる前のプロトタイピングの段階で仮のそれらしいアイコン画像を用意できれば手戻りも減らせそうです。


上記では、一般的な用途のアイコン画像に加え、用途の偏ったアイコン画像を気軽にためしたいという要望があります。アイコン画像の生成については、あらかじめ用意されたアイコン画像の色調を変更したりアウトライン・塗り潰しを切り替えたりするなど、組み合わせで実現する方法もあります。ただしこの場合、バリエーションを用意するのに手がかかってしまうし、用意されたものから逸脱するアイコン画像を手に入れることはできません。

ここでは、任意の対象がアイコンとして表現されている画像が欲しい、と言えそうです。あらかじめ用意した選択肢をこえたものが欲しいというような問題の解決に機械学習の手法が使えないか、というのを理由に今回の課題を考えてみます。

課題設定

上述したとおり、機械学習の生成で “任意の対象がアイコンとして表現されている画像” が得られること、という課題に設定します。ぼんやりしたところを以下で詳しくしていきます。

そもそもアイコンとは何なのかを考える必要がありそうです。通常、アイコンは何かの対象を記号的に表現したものが多い印象です。簡潔な表現からそれが指す物体や概念を判別できるようなものです。今回は課題をわかりやすくするため、何かの “物体” を記号的に表現したものとしてアイコンを考えます。”概念” については、記号的に表現するのは難易度が高いため今回の課題の範囲外としました。

物体をアイコンとして表現するのに使えそうな手法として、今回は機械学習のスタイル変換 (style transfer) を候補としてみました。突然出てきたスタイル変換ですが、これについては “AI で画像をゴッホの画風に変換する技術” などと呼ばれているもので目にしたことがあるかと思います。A Neural Algorithm of Artistic Style の論文で jcjohnson/neural-style などの実装があります。このスタイル変換をアイコン画像の生成に利用できないかと考えました。

スタイル変換での画像生成について、以下の2つのパターンを検討してみました。

  • もともとアイコンではない何かの物体の画像をアイコンスタイルに変換する
  • もともとアイコン画像になっているものを異なるスタイルのアイコン画像に変換する

あわよくば、両者をあわせて 実写画像 → アイコン画像 → いろいろな表現のアイコン画像 という変換ができれば都合がよいです。

ひとまずここでは前者をみていきます。(ちなみに後者はまた別なメンバーがトライしました)

“機械学習のスタイル変換を使い、アイコンではない何かの物体画像をアイコン画像に変換することでアイコン画像を生成する” という課題としてみます。

事例をさがす

素人が考えつくようなアイディアなのでおそらく先例がありそうです。具体的な手法としてはスタイル変換関連のものを探せばよさそうですが、もうすこし詳しいキーワードが欲しいところです。ひとまずとっかかりとして『生成 Deep Learning (David Foster 著 オライリー・ジャパン発行)』を見てみます。画像についての生成の項目を見たところ “CycleGAN” と “ニューラルスタイル変換” というキーワードが出てきました。当初の方向性としても間違ってはいなそうなので、このあたりで調べてみます。

それらしいキーワードで検索していくと、やろうとしていることに近い先例 (というかソノモノな先例) に達したのでそれを見ていきます。

Iconify: Converting Photographs into Icons (arXiv.org)

IN THIS PAPER, WE TACKLE A CHALLENGING DOMAIN CONVERSION TASK BETWEEN PHOTO AND ICON IMAGES. ALTHOUGH ICONS OFTEN ORIGINATE FROM REAL OBJECT IMAGES (I.E., PHOTOGRAPHS), SEVERE ABSTRACTIONS AND SIMPLIFICATIONS ARE APPLIED TO GENERATE ICON IMAGES BY PROFESSIONAL GRAPHIC DESIGNERS. MOREOVER, THERE IS NO ONE-TO-ONE CORRESPONDENCE BETWEEN THE TWO DOMAINS, FOR THIS REASON WE CANNOT USE IT AS THE GROUND-TRUTH FOR LEARNING A DIRECT CONVERSION FUNCTION. SINCE GENERATIVE ADVERSARIAL NETWORKS (GAN) CAN UNDERTAKE THE PROBLEM OF DOMAIN CONVERSION WITHOUT ANY CORRESPONDENCE, WE TEST CYCLEGAN AND UNIT TO GENERATE ICONS FROM OBJECTS SEGMENTED FROM PHOTO IMAGES. OUR EXPERIMENTS WITH SEVERAL IMAGE DATASETS PROVE THAT CYCLEGAN LEARNS SUFFICIENT ABSTRACTION AND SIMPLIFICATION ABILITY TO GENERATE ICON-LIKE IMAGES.

ICONIFY : CONVERTING PHOTOGRAPHS INTO ICONS. / KARAMATSU, TAKURO; BENITEZ-GARCIA, GIBRAN; YANAI, KEIJI; UCHIDA, SEIICHI.

MMART-ACM 2020 – PROCEEDINGS OF THE 2020 JOINT WORKSHOP ON MULTIMEDIA ARTWORKS ANALYSIS AND ATTRACTIVENESS COMPUTING IN MULTIMEDIA. ASSOCIATION FOR COMPUTING MACHINERY, INC, 2020. P. 7-12 (MMART-ACM 2020 – PROCEEDINGS OF THE 2020 JOINT WORKSHOP ON MULTIMEDIA ARTWORKS ANALYSIS AND ATTRACTIVENESS COMPUTING IN MULTIMEDIA).

研究成果: CHAPTER IN BOOK/REPORT/CONFERENCE PROCEEDING › CONFERENCE CONTRIBUTION

CycleGAN で写真画像とアイコン画像のスタイル変換を試してみたところ「いい感じにアイコン風画像生成の抽象化ができた」ということなので、まさに求めているものという印象です。なお、見つけたときはこれを再現できれば目的が達成できそうだと大船に乗った気持ちでしたが、後々考えの甘さに気付きます (実証の完遂に敬意です)。

詳細は論文の本文を参照してもらうとして、ひととおり読んでみたところ以下がキモだと解釈しました。

  • CycleGAN を使う
  • 段階的に学習する
  • 目的にあうデータセットを使う

それぞれについて見ていきます。

なお、論文では以下の3つ、

  • “実写の人間の画像” と “単色白黒アイコンの人間の画像” で学習しての変換
    • 限定的な物体についての実写画像とアイコン画像との変換
  • “実写の物体の画像” と “単色白黒アイコンの画像” で学習しての変換
    • 物体全般についての実写画像とアイコン画像との変換
  • “実写の物体の画像” と “ロゴ画像” で学習しての変換
    • 物体全般についての実写画像とロゴ画像との変換
    • アイコン画像の話をしているところで突然ロゴ画像が出てきますがそれについては後述

が検証されていますが、より汎用的で良好な結果が得られたと思われる3つめの再現をこころみます。

CycleGAN を使う

CycleGAN とは何者なのか、というところから見ていきたいです。その前に GAN について軽く触れておきます。

GANとは何なのか?

GAN (敵対的生成ネットワーク, Generative adversarial networks) を Wikipedia で見てみると以下のように説明されています。

敵対的生成ネットワーク (てきたいてきせいせいネットワーク、英: GENERATIVE ADVERSARIAL NETWORKS、略称: GANS)は、2014年にイアン・グッドフェローらによって発表された教師なし学習で使用される人工知能アルゴリズムの一種であり、ゼロサムゲームフレームワークで互いに競合する2つのニューラルネットワークのシステムによって実装される[1]。

GANSは生成ネットワーク(GENERATOR)と識別ネットワーク(DISCRIMINATOR)の2つのネットワークから構成される。例として画像生成を目的とするなら生成側がイメージを出力し、識別側がその正否を判定する。生成側は識別側を欺こうと学習し、識別側はより正確に識別しようと学習する。このように2つのネットワークが相反した目的のもとに学習する様が敵対的と呼称される所以である。

HTTPS://JA.WIKIPEDIA.ORG/WIKI/%E6%95%B5%E5%AF%BE%E7%9A%84%E7%94%9F%E6%88%90%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF (2020年10月20日 (火) 19:27 時点の版)

ざっくり言えば、

  • 生成する役と識別する役が互いに高めあうように学習して、上手に生成ができるようになる仕組み
  • ニューラルネットワークで作られている (ここでのニューラルネットワークはディープラーニングの一種と言ってよさそうです)

というものです。

CycleGANとは何なのか?

戻って CycleGAN についてです。これは論文の本文をざっと要約してみます。

CycleGAN はドメイン変換手法で、一対一で対応する画像の情報なしで2つのドメイン間のマッピングを決めることができます。今回のケースで言えば、実写の物体の画像とアイコン画像という2つのドメインについて、実写の物体とアイコンの一対一の対応関係の情報なしでそのマッピングを決めることができます。今回のような課題の場合、実写の車の画像と車を表わすアイコン画像といった組み合わせを用意することは非現実的です。pix2pix で使うようなデータを用意することは難しいでしょう。

CycleGAN では双方向に一対一のマッピングを実現するために “cycle-consistency loss” を使っています。前出の『生成 Deep Learning』の用語で言うなら “復元性損失” と訳されるものでしょうか。今回で言えば実写の物体の画像とアイコン画像の変換を双方向に行います。双方向の変換が上手にできるならば、実写の物体をアイコン画像に変換し、さらにそのアイコン画像を実写の物体の画像に変換すると元の実写の物体の画像とよく似たものを作れるはずです。

ざっくり言えば、

  • 2つのドメイン間の対応情報なしにマッピングを決めることができる
  • 双方向に変換する仕組みを使っている

というものです。より詳細は論文の本文や CycleGAN の原論文を参照してください。なお CycleGAN も、馬とシマウマの変換 (Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks) で有名です。

実装は junyanz/pytorch-CycleGAN-and-pix2pix を利用したとのことなので、これにならいます。

補足: CycleGAN では “identity mapping loss” (同一性損失) という色の不変性に関連する仕組みが使われています。実写画像と白黒アイコン画像の変換を検証する際に、色は重要な要素ではないためこの損失を弱めたとあります。今回は実写の物体の画像とロゴ画像とを利用するパターンの再現を目標としているので、とくに手心を加えずやっていきます。

段階的に学習する

学習につかうデータセットのバリエーションに対してうまく対処するため、段階的な学習という手段を使ったとあります。

実写の物体の画像とアイコン画像との間の変換は、馬とシマウマのときのように特定の対象同士を扱うものではありません。論文中の検証のうちの1つめ、”実写の人間の画像と単色白黒アイコンの人間の画像で学習しての変換” は、馬とシマウマのケースに近いと考えられます。しかし “実写の物体” の画像は人間だけでなく、車やボールなどいろいろなバリエーションがあります。またアイコン画像についても、それぞれが全く異なる抽象化の施された表現になっています。このバリエーションへ対応するために PGGAN という手法にならい、段階的な学習で対処しています。今回は前出の CycleGAN の実装で --continue_train フラグをつけてモデルをファインチューニングしていくことになります。

PGGAN (tkarras/progressive_growing_of_gans) という新しいワードが出てきました。これはざっくり言えば “低解像度の画像から学習をはじめて層を増やしていくと訓練の速度があがり、安定性が向上する” というものです。32×32 ピクセルのサイズから 64×64 → 128×128 → 256×256 と段階的にファインチューニングして学習をしたとあります。

目的にあうデータセットを使う

今回は “実写の物体の画像とロゴ画像で学習しての変換” を再現するため、以下のデータセットを用意します。

  • 実写の物体の画像として COCO – Common Objects in Context
    • 物体認識やセグメンテーション、キャプションのアノテーションデータと画像を提供するデータセットです
    • 今回はアノテーションとして “2017 Train/Val annotations” を、画像データとしてそれに対応する “2017 Train images” をもとにデータを作成します
    • アノテーションの情報をもとに、画像から物体だけを切り抜き白背景にして正方形にし、リサイズして使います
  • ロゴ画像として LLD – Large Logo Dataset
    • favicon や Twitter のプロフィール画像を集めたデータセットです
    • 今回は LLD-logo (Twitter のプロフィール画像をロゴととらえ集めたもので、400×400 ピクセルの画像) からランダムに選んだ 20000 画像をリサイズして使います

実写の物体の画像

実写の物体の画像をアイコン画像に変換するにあたり、その元となる実写の物体を切り出す必要があります。アイコン画像は通常、背景持っていません。ただ、そのような画像のデータセットは存在しないので、COCO のデータセットをアノテーションの情報で切り抜きデータを作成しています。ここで使うアノテーション情報は、ピクセル単位で画像のどこに何の物体があるかという情報を使います。

また、対象の物体が小さすぎる場合も除外します。COCO のアノテーション情報は、ある画像内に存在する物体の領域の情報なので、対象が小さく写っていたり部分的に写っているものも多いです。本来ならば対象がわかりやすく写っている画像が好ましいのですが、そのようなデータセットは存在しないため COCO をよしなに加工して利用しています。結局のところ、今問題としているのは識別ではなく生成なので、アイコンとして生成したい見栄えのよい画像が用意できるとうれしいです。

ロゴ画像

論文内では、実写の物体の画像と白黒のアイコン画像とを使った検証も行なっていますが、今回は以下の理由から白黒アイコン画像での再現を見送りました。

  • Microsoft PowerPoint で提供されている白黒アイコン画像を使ったとあるものの、そもそもそのアイコン画像たちを特定できていない
  • 数が少なく、別途データ拡張が必要 (オリジナルの画像を回転・拡縮・ノイズ追加をしてデータを水増しする工夫が必要)
  • 白黒アイコン画像の場合には同一性損失を弱めたとあるものの (前述)、どの程度弱めたのかは詳しく言及されていないため試行錯誤の必要がある

ロゴはテキストを含んでいたり色があったりと、その用途と形状に差異はあるものの、抽象的なデザインという点でアイコンに似ているためアイコン画像とともに試されています。検証でも悪くない結果を得られたようなので、ロゴ画像で再現をこころみます。ロゴ画像については LLD のデータセットで十分な数が提供されているためデータ拡張が不要な点もありがたいです。

下調べ編 まとめ

ざっくりまとめます。

  • アイコン画像の生成に CycleGAN が使えそう
  • ただし段階的な学習などひと工夫が必要
  • データセットもぴったり要件にあうものはないのでひと工夫必要

スタイル変換でアイコン画像を生成できないか?というあいまいな状態からすこし具体的になってきました。以上に見てきた内容をもとに画像生成を実践してみます。実践編に続きます

AWS Global Acceleratorの紹介&速度検証

0

はじめに

データイノベーション部浅田です。

アプリケーションにとって、どれだけサクサク動くかというのは重要な指標の一つです。Webアプリケーションやモバイルアプリケーションなどのネットワークの利用を前提としたアプリケーションにおいては、ネットワークのレスポンスの良さ、というのも重要なファクターになります。

せっかく情熱などをもって構築したサービスも、コンテンツの表示に時間がかかってしまうと「何よりも、速さが足りない!」と思われてしまいかねません。

そこで、今回ご紹介するサービスがこちら!

AWS Global Accelerator(以下Global Accelerator)

となります。

より詳しい特徴は上記をご確認頂ければと思いますが、色々あるメリットのうち、今回お伝えしたい内容としては、こちらのサービスを使うとネットワーク速度改善のメリットが得られるという点です。

「ネットワーク速度」はインターネットサービスとして限りなく速いことが望ましいです。そこで今回は、上記の二点について、Global Acceleratorを使わなかった場合と使った場合にどれだけかわるのかを検証して見たいと思います。なお、EC2にNginxをインストールし、そのレスポンスを確認する、という手順で見ていきます。

検証

前提

EC2インスタンスタイプ: m5.large
Nginx: 1.18.0
クライアント: curl 7.54.0
場所: アピリッツ社内(東京都渋谷区)

[EC2 IP]
東京: 54.250.246.155
バージニア: 34.229.65.223

[Global Accelerator IP]
75.2.96.126
99.83.178.155

なお、速度の比較として、10回読み込みを行い、その平均値を計測するものとします。

準備

東京リージョンとバージニア北部リージョンとにEC2を起動して、以下のコマンドでnginxのインストールおよびダミーファイルを準備します。

# EC2内で実行
sudo amazon-linux-extras install nginx1
cd /usr/share/nginx/html/
sudo dd if=/dev/zero of=1M.dummy bs=1M count=1
sudo dd if=/dev/zero of=20M.dummy bs=1M count=20
sudo service nginx start

計測用に以下のスクリプトをspeed-test.shの名前でローカルに用意します。

# 接続
echo "### サンプリング(秒)"
for i in {1..10}; do curl -XGET -w "%{time_total}\n" -o /dev/null -s ${1}; done | tee tmp.lst

# 平均値出力
echo "### 平均(秒)"
awk '{sum+=$1} END {print sum/NR}' tmp.lst
rm tmp.lst

最後に、Global Acceleratorを作成し、東京リージョンのEC2にエンドポイントの向き先を設定します。以上で、準備完了です。

第一弾 東京リージョン

第一弾として、東京リージョンへのアクセスでのGlobal Accelerator有無の速度についての比較をします。

1Mのファイル

まずは、直接EC2にアクセスします。

$ sh speed-test.sh http://54.250.246.155/1M.dummy
### サンプリング(秒)
0.109332
0.119329
0.131457
0.129000
0.115801
0.110114
0.132545
0.113515
0.112620
0.111140
### 平均(秒)
0.118485

次にGlobal Accelerator経由です。

$ sh speed-test.sh http://99.83.178.155//1M.dummy
### サンプリング(秒)
0.109456
0.105758
0.107199
0.107842
0.105607
0.108402
0.110008
0.104493
0.106547
0.109290
### 平均(秒)
0.10746

ん?少し早くなったかな、ぐらいでほぼ差はないですね。

20Mのファイル

直接EC2へのアクセスの場合を計測します。

$ sh speed-test.sh http://54.250.246.155/20M.dummy
### サンプリング(秒)
1.816273
1.810556
1.807303
1.802766
1.808038
1.808243
1.800309
1.804496
1.986049
1.805717
### 平均(秒)
1.82498

次にGlobal Accelerator経由です。

$ sh speed-test.sh http://99.83.178.155/20M.dummy
### サンプリング(秒)
1.802430
1.806430
1.804574
1.802140
1.800463
1.798066
1.802565
1.798186
1.846157
1.800256
### 平均(秒)
1.80613

ほぼ変わらないですね。

Global Acceleratorはアクセス元が対象リージョンに近いとそのメリットをあまり享受できないようです。

第二弾 バージニア北部リージョン

次に、国外のリージョンであるバージニア北部リージョンへのアクセスでのGlobal Accelerator有無の速度についての比較をしたいと思います。Global Acceleratorのエンドポイントをバージニア北部リージョンのEC2に切り替えます。

1Mのファイル

まずは直接EC2へのアクセスのケースです。

$ sh speed-test.sh http://34.229.65.223/1M.dummy
### サンプリング(秒)
3.134302
3.162077
3.117981
3.098290
3.150670
3.066146
3.134135
3.137177
3.134533
3.180120
### 平均(秒)
3.13154

次にGlobal Accelerator経由の場合です。

sh speed-test.sh http://99.83.178.155/1M.dummy
### サンプリング(秒)
1.040463
1.034937
1.036202
1.040337
1.032864
1.034404
1.035367
1.032810
1.041944
1.032675
### 平均(秒)
1.0362

お、およそ三倍の速度が出ているようです。

20Mのファイル

まずは直接EC2へのアクセスの場合です。

$ sh speed-test.sh http://34.229.65.223/20M.dummy
### サンプリング(秒)
7.312831
5.675996
6.660435
12.293564
7.569658
16.370434
13.757100
8.670905
16.401453
8.794712
### 平均(秒)
10.3507

時間もそこそこかかってますが、今までに比べてバラツキが大きくなっているのも気になります。(念のため、数回サンプリングしてみましたが、どのケースもバラツキは大きかったです。)

次にGlobal Accelerator経由です。

$ sh speed-test.sh http://99.83.178.155/20M.dummy
### サンプリング(秒)
2.739648
2.741390
2.741749
2.737428
2.763309
2.729312
2.731547
2.742664
2.736493
2.772755
### 平均(秒)
2.74363

かなり早くなりました。7秒も世界を縮めてしまいました。そして、ばらつきもほとんどなく、安定した速度が出ています。ついに見つけました、Global Acceleratorの真髄を!

第三弾 東京リージョン内のEC2からバージニア北部リージョンのEC2へのアクセス

第一弾と第二弾とでは、ユーザのアクセスを想定して筆者のローカルからアクセスして計測してみましたが、最後に東京リージョンのEC2からバージニア北部リージョンのEC2へアクセスした際の時間を計測してみます。

1Mのファイル

まず、直接EC2です。

$ sh speed-test.sh http://34.229.65.223/1M.dummy
### サンプリング(秒)
1.370514
1.372094
1.367089
1.380025
1.339979
1.375507
1.333260
1.373431
1.338106
1.367856
### 平均(秒)
1.36179

素でもかなり速くなっています。AWS内の回線品質の良さを伺わせます。

次にGlobal Accelerator経由です。

$ sh speed-test.sh http://99.83.178.155/1M.dummy
### サンプリング(秒)
0.870017
0.873519
0.872324
0.867491
0.870899
0.874320
0.875362
0.870478
0.873536
0.869653
### 平均(秒)
0.87176

倍とまではいきませんが、十分速くなっています。EC2内からアクセスした際にも、Global Acceleratorの恩恵は得られるということですね。

20Mのファイル

直接EC2の場合を計測します。

$ sh speed-test.sh http://34.229.65.223/20M.dummy
### サンプリング(秒)
3.528554
3.487068
3.753335
3.572857
3.675303
3.662903
3.599749
3.639234
3.552648
3.611756
### 平均(秒)
3.60834

ローカル環境からのアクセスに比べて十分に高速であるとともに、速度の安定度も感じられます。

次に、Global Accelerator経由です。

$ sh speed-test.sh http://99.83.178.155/20M.dummy
### サンプリング(秒)
2.467313
2.235525
2.159171
2.311107
2.023744
2.461509
2.320583
2.027042
2.169427
2.033224
### 平均(秒)
2.22086

さらに速くなっていますね。

検証結果

計測された、速度改善率をまとめると以下の通りです。

ロケーション1Mファイル20Mファイル
ローカル to 東京リージョン約9%約1%
ローカル to バージニア北部リージョン約67%約73%
東京リージョン to バージニア北部リージョン約36%約38%

以上のことより、Global Acceleratorは特に離れたリージョンへのアクセス改善に効果を発揮するということが言えると思います。また、ファイルサイズが大きい方がメリットも大きくなった結果となりました。

まとめ

Global Acceleratorを使用することで、特に遠く離れたリージョンのサービスにアクセスする際に、かなり速度面でメリットを得られることがわかりました。特に大きなファイルをダウンロードする際には、単純な速度面もさることながら、安定した通信環境につなげるというのもメリットとなるかとおもいます。

今回は速度面に焦点を当てましたが、Global Acceleratorはその他にも利点があります。例えば、グローバルにサービスを展開している場合には、それぞれのリージョンのApplication Load Balancingの前段に配置することで、指定したWeightに応じてリクエストを各リージョンに割り振ることもできます。一つのリージョン内で運営する際にも、Blue Greenデプロイに活用することも可能でしょう。

また、Application Load BalancingではIPアドレスは可変のため、CNAMEで名前解決するように設定しますが、Apexドメインで名前解決する際にはCNAMEが設定できないことが問題になったりするケースも存在します。ですが、Global Acceleratorの場合は固定IPが振られるため、Aレコードで指定できるので、Apexドメインの問題が解消されます。

以上、Global Acceleratorの紹介&速度検証でした。

WEBマーケティング担当者が息抜きに見るサイト3覧

0

こんにちは。DB部の有馬です。

現在はマーケティンググループに所属していて、普段はGoogleアナリティクスを使ってクライアントのサイトにある課題を見つけたり、WEB広告の運用などをしています。

マーケティング関係の仕事はとても興味深く面白い部分も多いのですが、如何せん自分は集中力を持続させるのが苦手なので、8時間ずーっと手を動かし続けることができません。

なので、1日に2回くらいは息抜きにメディアサイトを見て気分をリセットすることにしています。

今回の記事では、そんな自分が息抜きに見てるサイトを紹介しようかと思います。

一応マーケティング関係のサイトが多いので、息抜きとはいえ勉強にはなっているはず・・・・です。

MarkeZine

■ヒトコトで言うと

「広告・マーケティングの最新情報がわかる!マーケター向け専門メディア」

■概要

毎日新しいマーケティング系の記事が更新されるWEBメディアです。読む頻度は一番高い。

更新頻度の高さもさることながら、とりあげられるテーマはどれも興味深いものが多く、タイトルを見るだけで読んでみたくなる記事ばかり。

会員システムがあり、一部の記事は会員にならないと読めませんが大体は未ログインでも読めます。(面白そうなタイトルのものは7割くらい会員にならないと読めないのがこのサイトの上手いところです。)

毎日更新されているのでその時その時で流行している話題が取り上げられることが多く、マーケティングに興味のない人でも楽しめる記事が多いのでぜひページを開いてみてください。

■URL

https://markezine.jp/

ITmediaマーケティング

■ヒトコトで言うと

「マーケ×ITのいまがよくわかる」

■概要

こちらもマーケティング系のメディアサイトです。

前述のMarkeZineと比べるとIT系の技術とマーケティングを組み合わせた話題・技術を取り上げた記事が多いサイトであり、技術系のトレンドを

追っている人であれば気になるようなタイトルの記事がズラッと並んでいます。

最近だと、サードパーティーCookieの利用制限によるデジタル広告への影響を取り上げた記事が特に面白かったですね。

「サードパーティーCookieの利用制限はデジタル広告にとって大きなチャンスでもある」

ただ会員登録をしてないと記事を読めないので、ひと手間は必要になります。(自分は登録しました。)

■URL

https://marketing.itmedia.co.jp/

note

■ヒトコトで言うと

「つくる、つながる、とどける。」

■概要

こちらはメディアというより記事投稿サイトですね。知っている方も多いのではないでしょうか。

マーケティング系の記事はもちろん、グルメ、ライフスタイル、デザイン、IT、漫画、ゲームなどありとあらゆるジャンルの記事が集まっています。

誰でも投稿できるので、地元の中学生が投稿している場合もあればプロのライターが投稿している場合もあり、内容は千差万別。

内容が充実していて勉強になる記事を見つけるのはなかなか骨が折れますが、その分見つけたときは非常に得した気持ちになれます。

読み物が好きな人はたまに覗いてみると、楽しい記事に出会えるかもしれませんね。

ちなみに自分は「はてなブログ」の方が好きです。

■URL

https://note.com/

以上の3つが、自分の気に入っているサイトです。

どのサイトもコンテンツが多く、全部読もうと思ったら余裕で1日は使ってしまいますが、1~2記事読む程度なら5分程度で終わります。

ちょっと集中力落ちて来たな、と思ってきたら是非思い出してみてくださいね。

初めてのAdobeXDで優秀だと思ったプラグイン【9選】

0

デジタルビジネス部所属、20卒の武田です!
入社してから早半年が経ちました、あっという間ですね。
優しい先輩たちに助けられながら、業務にも少しずつ慣れてきたかなと思います。
(トライアンドエラーの日々です)

本日はワイヤーフレームやデザインカンプの作成でよく使われるAdobeXDのプラグインについてご紹介していきます。
XD自体は入社してから初めて使ったのですが、

さすがAdobe製品

PhotoshopやIllustratorなどを使っていたからか、直感的でスムーズに操作方法を学習することができました。
パワーポイントやエクセルなどで作成するよりも圧倒的に時間短縮できて作業効率も上がるのですが、もっと便利に使いたい!と思いたくさんのプラグインを試してみました。
その中で、使う頻度が高いものや便利!と感じたおすすめプラグイン9個を紹介していきます☆


パーツ おすすめプラグイン(3選)

1. Calendar|カレンダー

カレンダーを一から作るのって大変ですよね、こちらのプラグインは指定した月のカレンダーをXD上に生成することが可能です。
セルのサイズ変更や週の曜日始まり、曜日の表示形式なども調整できるとてもシンプルで使いやすいプラグインです。

2. unDraw|イラスト素材

シンプルでおしゃれなイラストが揃っていて、配色を変えることもできるプラグイン。
イラスト数は多いのに無料で会員登録も不要なのでとっても優秀です。ファイルはSVG・PNGの2種類の形式から選ぶことができます。統一性のある見た目になるため、ガラッとプロフェッショナルなデザインへと変わります。

3. Icondrop by Iconscout|アイコン素材

アイコンに限らずイラストや写真まで、数百万個あるライブラリから検索し、アートボード上に簡単に挿入することができるプラグイン。無料・有料とあるのですが、無料素材でも量が多いため簡単にお目当ての素材を見つけ出すことができます。また、無料版ではPNG形式のみの利用が可能です。
※利用する際にはメールアドレスとパスワードを記入するだけの簡単な会員登録が必要です


効率化 おすすめプラグイン(3選)

1. Artboard Plus|アートボード整列機能

アートボードの整列に関しての効率化を図るためのプラグイン。
ばらばらになっているアートボードを均等に配置したり、選択したオブジェクトのサイズと同じアートボードを作成したり、レイヤーを名前順に並び替えることもできます。

2. Resize Artboard to Fit Content|コンテンツ量に合わせてアートボードをリサイズ

コンテンツ量に合わせてアートボードの高さを変更するのは意外と面倒で時間がかかりますよね。
その時に使っていただきたいプラグインはこちらです。
サイズ変更したいアートボードを全て選択し、プラグインを起動させると一瞬でリサイズされます。

3. Swapper|オブジェクト入れ替え

2つのオブジェクトの位置を逆にしたい、シンプルなことですが意外と面倒。そんな時はSwapperを使うとオブジェクトの位置をサッと簡単に入れ替えることが可能です。グループ化されているオブジェクトも対象なので作業効率が一気にアップします。


その他 おすすめプラグイン(3選)

1. Stark|色盲・色弱シミュレーション

色盲や色弱のシミュレーションをしたり、コントラストをチェックすることができるプラグイン。
こちらは無料版、有料版とあるのですが、無料版で使えるのが「Color Blind Simulation(カラーブラインドシミュレーション)」と「Check Contrast(チェックコントラスト)」の2つ。

カラーブラインドシミュレーションは様々な症状の色盲/色弱を持ったユーザーにはどのように見えるのかをチェックすることができます。
チェックコントラストは選択しているオブジェクトの背景色とテキスト色のコントラスト比を数値で確認することができます。

2. Confetti|背景パターン作成

Confettiを使うと、1クリックで簡単にインパクトがある背景パターンを生成することが可能です。指定した図形を複製し、複数の機能を合わせることにより、このブログのメインビジュアルのような図を作ることができます。
(業務であまり使う事はないのですが、覚えておいても損はないと思います!)

3. Whiteboard|コミュニケーション

XD上でアイデア出しや意見などを交わせるプラットフォームを用意しているプラグイン。
テンプレートとしてホワイトボード、ブレインストーミング、フローチャートやマインドマップなどといったコミュニケーションメソッドが備わっていて、さらに各メソッドの使い方まで書いてあるので初心者でもとても使いやすいです!
リモートワークでもコミュニケーションの大切さを忘れないよう開発されたプラグインですね☆


おわりに

Adobe XDのアップデート頻度は月に1回ぐらいで、その度に便利な機能がたくさん追加されています。
それに伴い、新しいプラグイン既存プラグインのアップデートもよくあるので、常にチェックしておいたほうが良さそうですね。
プラグインを使いこなすことで、手間の改善や作業効率を上げられること間違いなし!
ストレスフリーな作業環境を目指すために、是非積極的に取り入れてみてください♪

iWGAN-LCを用いたロゴ画像生成

0

概要

GANを応用したiWGAN-LC(LayerConditional)というモデルを使ったロゴ画像生成を行いました。 ロゴ画像生成にはiWGAN-LCの実装である https://github.com/alex-sage/logo-gen を使いました。 はじめに、iWGAN-LCとその元となったモデルの簡単な説明をしていきます。

GAN

敵対的生成ネットワークと呼ばれるモデルで、教師なし学習で画像生成などが行なえます。 GANの特徴は、贋作を作るモデル(生成器)と、贋作か本物か見分けるモデル(識別機) の2つのモデルが使われる点です。贋作を作るモデルは、本物そっくりの贋作を作るように訓練され、見分けるモデルはより偽物を見破れるように、切磋琢磨する形で訓練されていきます。

ただ、GANには以下の問題点がありました。

  • 勾配消失が発生する
  • モデルの良否を判断する明確な指標がない
  • モード崩壊が起こる

これらを改善しようとしたモデルがWGANになります。

WGAN

WGANはWasserstein GANの略で、GANとの違いは以下になります。

  • GANでは損失関数にJSD(Jensen-Shannon divergence)が使われていたが、WGANではWasserstein距離を使用している。(勾配消失問題への対処)
  • Wasserstein距離を使うための制約として、重みのクリッピングをしている。

WGANには以下の問題点がありました。

  • 重みのクリッピングを行ったことで、学習が不安定になる。

学習の不安定性の解消を図ったのがiWGAN-LCになります。

iWGAN-LC

iWGAN-LCはWGANを拡張したモデルで、WGANとの主な違いは以下になります。

  • ラベルを事前にクラスタリングし、ワンホットベクトルとして、潜在ベクトルに追加
  • 追加の特徴マップを各畳込み層と線形層(生成器、識別機の両方)の入力に追加

実行環境構築

ロゴ画像生成処理にはGPUを使用するため、EC2のGPU利用可能なインスタンスを使う前提で環境構築を行います。また、今回はゼロからモデルの訓練は行わず、公開されているpretrainedモデルを利用します。

まずはDockerfileの作成と、必要なソースを用意していきます。それらが準備できたら、EC2上でDockerビルドしていきますが、ソースをEC2に配置しやすいように、適当なgitリポジトリにpushしておくと楽かもしれません。また、データセット、pretrainedモデルはファイルサイズが大きいので、EC2上で直接ダウンロードして配置するほうがよいかもしれません。(お好みで)

EC2インスタンスの設定

利用するインスタンスは以下になります。

  • AMI
    • Deep Learning AMI (Ubuntu 18.04) Version 36.0 – ami-0bc87a16c757a7f07
  • インスタンスタイプ
    • g4dn.xlarge (GPUが使えるものであればOK)

logo-genの環境要件

python 2系
tensorflow 1.3
tensorflow-gpu 1.3
cuda 8.0
cudnn 6

上記のpython、cuda、cudnnが入っているnvidiaのdockerイメージを利用して環境構築していきます。cuda, cudnnのバージョンは、tesorflowのバージョンにあったものを選択する必要があるため、別のバージョンだと動かない可能性が高くなります。tensorflowなどについてはDockerfile内でpipでインストールしていきます。Dockerfileは以下の内容で作成します。

Dockerfile
FROM nvidia/cuda:8.0-cudnn6-runtime-ubuntu16.04

SHELL ["/bin/bash", "-c"]

ENV APP_ROOT /app
ENV LANG=C.UTF-8

RUN apt-get update -qq && \
   apt-get install -y --no-install-recommends \
   build-essential \
   libboost-all-dev \
   wget \
   vim \
   openssh-client \ 
   graphviz-dev \
   pkg-config \
   git-core \
   openssl \
   libssl-dev \
   libffi6 \
   libffi-dev \
   cmake \
   unzip \
   python-dev \
   python-pip \
   python-setuptools \
   curl && \
   apt-get clean && \
   rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
   mkdir /install

RUN pip install --upgrade pip
RUN pip install backports.functools-lru-cache==1.5 \
  backports.shutil-get-terminal-size==1.0.0 \
  backports.weakref==1.0rc1 \
  bleach==1.5.0 \
  cycler==0.10.0 \
  decorator==4.3.2 \
  enum34==1.1.6 \
  funcsigs==1.0.2 \
  h5py==2.9.0 \
  html5lib==0.9999999 \
  ipython==5.8.0 \
  ipython-genutils==0.2.0 \
  kiwisolver==1.0.1 \
  Markdown==3.0.1 \
  matplotlib==2.2.3 \
  mock==2.0.0 \
  numpy==1.16.1 \
  pathlib2==2.3.3 \
  pbr==5.1.2 \
  pexpect==4.6.0 \
  pickleshare==0.7.5 \
  Pillow==5.4.1 \
  prompt-toolkit==1.0.15 \
  protobuf==3.6.1 \
  ptyprocess==0.6.0 \
  Pygments==2.3.1 \
  pyparsing==2.3.1 \
  python-dateutil==2.8.0 \
  pytz==2018.9 \
  scandir==1.9.0 \
  scipy==1.2.1 \
  simplegeneric==0.8.1 \
  six==1.12.0 \
  subprocess32==3.5.3 \
  tensorflow==1.3.0 \
  tensorflow-gpu==1.3.0 \
  tensorflow-tensorboard==0.1.8 \
  tqdm==4.31.1 \
  traitlets==4.3.2 \
  wcwidth==0.1.7 \
  Werkzeug==0.14.1 \
  --no-cache-dir

COPY src $APP_ROOT/src

WORKDIR $APP_ROOT/src

Dockerfileと同じディレクトリに、log-genリポジトリのソースを含めて、srcという名前で配置します。以下のような配置になります。

my-src/
  Dockerfile
  src/

次にデータセット配置用のディレクトリを作成します。

mkdir src/wgan/data

データセット、pretrainedモデルの配置

データセット をダウンロードして、上記で作成したsrc/wgan/dataに配置します。次に pretrained model をダウンロードして、 src/wgan/runs に配置します。pretrained modelはzip圧縮されているので解凍し、中の設定ファイルの修正をします。

unzip model_WGAN_LLD-icon-sharp_rc_128.zip
vim model_WGAN_LLD-icon-sharp_rc_128/config.json

"DATA": "LLD-icon-sharp.hdf5" を以下のように修正
↓
"DATA": "data/LLD-icon-sharp.hdf5"

Docker ビルド

Dockerfileのあるディレクトリで、以下のコマンドを実行します。

docker build -t logo-gen .

GPUの確認

コンテナに入ってGPUが認識されているか確認します。

docker run --gpus all -e NVIDIA_DRIVER_CAPABILITIES=all -v $PWD/src:/src -it logo-gen /bin/bash
nvidia-smi

GPUが1つ認識されていることが確認できれば大丈夫です。

画像生成

実行するディレクトリに移動して、ipythonを起動します。

cd src/wgan
ipython

以下のコマンドで画像生成を実行します。

import tensorflow as tf
import numpy as np
import vector
from logo_wgan import WGAN

session = tf.Session()
wgan = WGAN(session, load_config='LLD-icon-sharp_rc_128')
vec = vector.Vector(wgan)
vec.show_random(save="./result.png")

result.png に以下のようなロゴ画像群が出力されていれば成功です。(以下の画像と同じ画像は出力されません。)

まとめ

  • EC2のGPUインスタンスを使ってロゴ生成ができた。
  • 今回出力されたロゴ画像群は、品質的にそのままロゴとして使えるわけではなさそう。
  • ただし、シェイプや色、その他の特徴をなめらかに変化させることが可能なモデルなので、調整を行うことで、使えるロゴが出力できる可能性はありそう。

参考

https://github.com/alex-sage/logo-gen

【SEO効果あり!?】記事執筆の際に参考になる文字数のこと

0

◆はじめに

 記事をいざ書くときにどうやって書こうか考えたときに
 スピリッツ元気玉Q&Aを確認したところ

 Q:どんな記事を書けばいいのか?
 A:内容、文字数、言語、すべて自由です。

 と、書いてあるのを拝見しました。
 「とはいいつつ文字数とか決めてくれた方が」と思ったり
 「あんまり文章を書くのが得意じゃないから」と思ったり
 そういった方もいらっしゃるのではないでしょうか。

 かくいう自分もそう思った中で、記事を書こうとしたときに「文字数」について調べていたら
 「文字数」のことだけで記事になりそうだったので方針を変更しました。 
 これから執筆される方の参考になればと思います。

本記事でわかること:記事を書くときにちょっとだけ役立ちそうな「文字数」のこと

◆結局何文字書けばいいの?

 記事を書く際に最適とされる文字数はどれくらいなのでしょうか。
 まず、最適云々関係なく1ページの文字数は600文字以上が目安ともいわれています。 
 その中で、人を集める記事の目安は1,000~2,000文字といわれているようです。
 記事読み慣れていない人からしたら1,000文字!2,000文字!と言われたところで
 どのくらいの長さかわかりませんね。頭の片隅にでも入れておきましょう…。

 (ちなみに人間は1分間に500文字、早い人で1,500文字を読むことができるそうです。)
 
 と、言われているものの無理に2,000文字にしたらいいわけではないのが難しいところです。
 記事に人を集めるには、あくまでコンテンツとしての充実が重要になります。
 500文字で終わって気持ちの良い記事を、無理に2,000文字にしてはいけないということですね。
 鮮度が大事な情報記事などは、パッと読める長さが重要といえます。
 
 なお、SEOにおける観点では、Googleは文字数は関係ないと表明しています。
 SEO関連のサイトにも「SEOと文字数には因果関係はありません」と書いてあります。
 しかし、SEO上位のページをたくさん調べた方の調査結果は、
 「SEO順位の高い記事は、ある程度の文字数を有していることは確かである」とのことです。
 人々が役立つ充実したコンテンツを執筆したらそれなりの文字数になっているのでしょう。

 

 それでも文字数に縛られたい方は、600、1,000、2,000などの文字数を目安に執筆しましょう。
 思わぬSEO効果があるかもしれません。

◆タイトルの文字数の目安は?

 本文の次はタイトルの文字数を考えましょう。
 一般的にSEOにおけるタイトルタグは30文字前後がよいとされています。
 これは検索結果が表示されたときに、そこまでであれば省略されずに表示されるからです。
 記事ページ自体のSEO順位で上位を狙うには、参考にしてもいいかもしれません。

 もう一つの考え方に「一度に人間が認識できる文字数」というものがあります。
 これもまた個人差はあるでしょうが、12~13文字といわれています。
 アピリッツ魂のサイトを回遊してる人に瞬時に見つけて興味を惹いてもらうためには
 この数字を気にしてもいいかもしれません。
 Yahoo!のニュースタイトルなどにもこの考え方が使われており、
 興味関心を引きクリックしてもらいやすくする工夫がみられます。
 この文字数の話は、プレゼンに使用するスライドでも同じことが言えます。
 1スライド、1テーマ、12文字のスライドを作る方もいるかもしれません。

 そのほか新聞の見出しは9~11文字、
 TV番組のテロップは1行15字以内を意識しているとの情報もありました。

 今ではYouTubeの方が主流でしょうか。サムネイルや字幕にも活かせそうですね。
 やや脱線しましたが、記事タイトルは簡潔で伝わりやすいことであればいいでしょう。
 読み手が必要な情報がコンパクトに収まっていることが美しく、伝わりやすいです。

◆1文の文字数って気にしたことある?

 本文やタイトルの話をしてきましたが、次はもっと細かい話です。
 文章を書き連ねていく中で、気づかないうちに1文がながーくなってしまっていたり
 短い文の繰り返しになってしまったりしていることがありませんか?
 平均的に、1文は平均40文字ほどが良いと言われています。
 また、文章内容や、出てくる単語にもよりますが
 60字を超えると読みづらくなってしまう傾向があるらしいです。
 数字がたくさん出てきたり、タイの首都の正式名称を書かなければいけない場合は
 60文字なんか気にしていられませんが…

◆まとめ

 ①本文②タイトル③1文
 今回は、こちらの3つについて、ちょっとだけSEOに効果があるかもしれない、
 ちょっとだけユーザーが読みやすくなるかもしれない文字数のことを書きました。
 あくまで参考です、ご了承ください。
 そういえば、目安で出てきた2,000文字ってどれぐらいなんでしょうか。


 本記事は約、2,000文字です。

意外と知られていない?アピリッツのクリスマスツリー担当に密着!

0

今年もいよいよ寒くなってきましたね!アピリッツでは会社の雰囲気をより良くするために、クリスマスの時期が近づくと毎年クリスマスツリーを飾ります。

また、内定者同士が知り合うきっかけ作りを目的として毎年内定者インターンのみなさんに各フロアのクリスマスツリーの飾り付けをお願いしています。今年も 続々とインターン生が会社に来てくれています!本日はそのクリスマスツリー作りの当日の様子をお届けします。

さっそく、まずはなにも飾りのない木から組み立てていきます!

どんなツリーになるか楽しみですね!
徐々にできあがってきました……!

飾りつけをしているうちに、いつの間にかチーム戦になり「どこのチームのツリーが5F受付に飾られるか!?」という勝負に……

仕上げに取り掛かる様子。

クリスマスソングをBGMにかけながら皆で協力してできあがりました!

5階の受付に飾られたツリーはコチラ!受付がとても華やかになりました。せっかくなので他のツリーが気になる方は2階、3階も是非のぞいてみてください!インターン生の皆さんありがとうございました!

最後に記念撮影!

今年もあと少しですが2020年ラストスパート頑張りましょう!

「自分だけの物語で感動を生み出そう」夢中になれる物語の作り方講座

0

はじめに

アピリッツが日々開発しているようなゲームを作る上でも、面白いストーリーというのは素晴らしい強みになります。
もし面白いストーリーが自分で考えられたら、とても楽しそうですし、役立ちそうですよね。

でも、読者のみなさんの中に多いのは、こんなタイプかなと思います。

・面白いストーリーとつまらないストーリーがある事はたくさん体験してきている
・ただどういうものが面白いストーリーなのかは、うまく説明できない
・どうすれば面白いストーリーが書けるのかは、もっとよく分からない。

実は自分はアピリッツにプランナーとして入社する前、ライトノベルの小説家として活動しているキャリアがありました。
今回はその経験も活かして、上記のようなタイプの方々を主な対象に、
自分が思う「面白いストーリーの考え方」について話していきたいと思います。

今回のテーマはこちらです。

「いかにして夢中になれるストーリーを構築していくか」

これを、主にエンターテイメントのストーリーを対象にして書いていきます。

夢中になれるストーリーに必要なもの

夢中になれるストーリーとはどういうストーリーでしょうか?
これについては実に色々な考え方があるのですが、自分は一つの答えとして以下を信頼しています。

夢中になれるストーリー:「主人公の間違いが正される事を通じて、人生の隠された性質(テーマ)が体感できる物語」

これが、物語の書き手が最初に目指すべき地平だと、自分は考えています。
もちろん、他にも読み手を夢中にさせるのを加速させていく要素は存在します。
たとえば物語に「謎」や「驚き」といった要素を加えていく事(情報のコントロール)で、読者をより熱中させていく事ができます。
また物語から得られる感情が、大きくアップダウンのカーブを描いている事(感情のコントロール)も、読者をのめり込ませる力を発揮します。

ですが、これら情報のコントロールや感情のコントロールは、実は一番本質的な面白さではないと自分は考えています。

では、物語を読んで一番本質的な面白さを感じる瞬間とは何なのか。


それは「カタルシス」を感じた瞬間です。

カタルシスとは、「精神の浄化作用」の事であり、心の中に貯まっていた鬱積した感情が、物語を見る事によって解放され、それによって強い快感を得る事を指します。

このカタルシスを感じさせる事が出来たら、ストーリーとしては合格点が与えられるといっていいでしょう。
このカタルシスを感じさせるための一つの型となるのが、先ほどの「主人公の間違いが正される事を通じて、人生の隠された性質(テーマ)が体感できる物語」という表現です。

特に重要なのがクライマックスです。
上記の型におけるクライマックスでは、自分の間違いに気づいた主人公が、間違いによって起こっていた問題を乗り越えるため、自分の力の限りを尽くします。
その際に主人公の感情が爆発し、全力を超える全力を尽くして、ついに何かを乗り越える。その瞬間、観客は強いカタルシスを感じる事が出来るのです。

なぜカタルシスを感じるのかを説明します。
ここで主人公が抱いていた間違いというのは、多くの読み手にとっても心当たりがある間違いが、書き手によって選ばれている事が多いです。
そんな、読み手にとっても仇敵である、あるいは仇敵であった間違いに、主人公が最後にはちゃんと気づいて、何かの問題を乗り越える。
そんな姿を見ると、観客は人生の隠された性質が体感でき、それが自分にとっても関係がある間違いだからこそ、観客自身の精神も浄化されるのです。
これこそ、上記の型の物語がカタルシスを感じる理由です。

確かに、情報のコントロール、感情のコントロールを行う事で、物語の面白さをさらに増す事はできます。


ですが、あくまでゴールは観客にカタルシスを感じさせる事。
そう考えた方が、いい物語に仕上がる可能性は高いと自分は感じています。

具体的なストーリー構築手順

さて、では具体的にどうすればストーリーが書いていくのでしょうか。

ここでは、以下のような手法を採用していきます。

1.ログライン集め・選択
2.ログラインを膨らませてあらすじに・テーマ決め
3.キャラクター設定・世界設定を簡潔に考える
4.あらすじを膨らませてプロットに
5.キャラクター設定・世界設定をしっかりと書く
6.本文を書く

1.ログライン集め・選択

最初にやる事は、いわゆるログラインをたくさん作る事です。
ログラインというのは、物語のアイデアを、ツイッターのつぶやき程度の文字数で表現したものです。

例えば、桃太郎だったら以下のような感じです。
「川から桃とともに流れてきた桃太郎が、きびだんごで猿、鳥、犬を仲間にし、鬼を退治する物語」

こういうものをいくつもいくつも考えます。

ここでいきなり目新しい物語の種がいくつも思いつく人は、才能がある人だと思います。
ただ思いつかなくても面白いストーリーを書く事は全然可能です。

・アイデアの浮かべ方

アイデアというのはそもそも組み合わせの事です。
自分の好きな物語の要素、自分が現実で感情を動かされたものなどを、たくさん紙に書いて、その組み合わせを試して、アイデアを着想していきましょう。

それから、それらを検討していきます。

検討過程で考えるのは以下のような事です。

1.自分が強く興味を持てる事であるか、自分に密接にかかわったテーマを含んでいるかを確かめる
2.そのログラインを実際にもう少し長いあらすじに発展させてみて、可能性を見る
3.そのログラインをストーリーにする上で、何が問題になるのか、何が分からないままなのかを考える

この工程で一つ「これだ!」というログラインが決まったら、次に、それを1000文字前後のあらすじに発展させるのですが、それと並行してテーマを決めます。

2.ログラインを膨らませてあらすじに

さて、ログラインからあらすじを作りましょう。
あらすじは、起承転結を意識して作ります。起承転結にはそれぞれポイントがあります。

・起承転結のポイント

起では「主人公が間違えている事をうっすら描きつつ、主人公に目的を与える」というのを行います。
承では「主人公が目的に向かいながら間違え続ける→間違えのせいで事件が起こって、流れが変わる→主人公が現実を知り、新たな認識を得る」という流れを描きます。
転では「クライマックスに向けて読み手を驚かせつつ展開を盛り上げて、主人公が全力を出さないと勝てない壁との闘いに向かう」という形で結の準備をします。
結では「主人公が全力を出す過程で感情が盛り上がっていき、全力を超える全力を出してついに間違いを正し、観客にカタルシスを与える」という形で綺麗に終わります。

これらを、
起:200文字
承:400文字
転:200文字
結:200文字
くらいを目安に書いていきます。

さらに、この起承転結で主人公が間違いを正す過程で、観客は「今まで知らなかった人生の性質」を体感します。
それは「主人公の間違いが間違いであるという事の自己発見」とも言い換えられます。
ここで描かれている人生の性質を、今回は「テーマ」と定義します。
このテーマを、自分の考えた話に合った形で発見してあげましょう。

3.キャラクター設定・世界設定を簡潔に考える

ここで、キャラクターや世界の設定を本格的に考え始めます。これを考えると、しばしば前の段階のあらすじ・テーマが変わったりしますが、全く問題ありません。
クリエイティブな仕事というのは、ガチガチに順番に作っていくものではなく、フィードバックを受けて行ったり来たりしながら進んでいく方が、よりクオリティが高いものに仕上がりやすいからです。

キャラクターの設定、世界の設定にはそれぞれポイントがあります。

・キャラクターの設定のポイント

キャラクターは、バラバラに一人一人思いつくのではなく、メインキャラクター全員をセットで考えていく方が、物語にまとまりが出ていき、一貫してテーマ、つまり「人生の性質」を表現できます。

まず、キャラクターがストーリーでテーマに対して果たす役割を考えていきます。
理想は、それぞれのメインキャラクターが、同じテーマに対して異なるやり方でアプローチしている形です。
そして、それぞれのキャラクターに対して、何を間違えていて、どのように間違いに気づいて(あるいはどのように間違いに気づかず)、どのように変わるのかを設定していきます。
このメインキャラクターはライバルとか敵対者などと呼ばれる、主人公と対立するキャラクターを含んでいるべきです。
そしてこの敵役も、テーマを違った形で反映していたりすると、味わい深いストーリーになりやすいです。

・世界の設定のポイント

まず世界の設定の変化は、主人公の変化と対応している事が望ましいです。
ただし、単純に主人公が幸せになるから世界も幸せな雰囲気になればいいというわけではなく、主人公が死んだおかげで世界は幸せに包まれた、とかそういう形でも構いません。

また、世界設定は、「テーマをどのように描くか」という事を突き詰めていった結果生まれる形が望ましいです。
また、これを考える上では「環境、人間、技術」というフレームワークで、3つをそれぞれ組み合わせて考えていく形がいいでしょう。

例を一つ考えるとするなら、以下のような感じです。実際はそれぞれをもっと長く書き込んでいきます。
環境:氷でできた森
人間:イヌイット風の文化の魔法使いたちが少数で暮らしている
技術:氷でできた森から魔力を汲み出す装置で、熱を生み出せる

こんなセットを一欠片として、この欠片をいくつも生み出して、それらの間の関係性を構造化していきます。
いわゆるキャラクター間相関図みたいな形で、世界の欠片同士の関係性を図にするのです。
この欠片には人間が含まれるので、前の段階で考えたキャラクター設定やあらすじにも影響する事でしょう。
それらを上手くフィードバックして整えたら、次に進みます。

4.あらすじを膨らませてプロットに

あらすじを膨らませて、個々の出来事を順番に書いたプロットを書いていきます。
プロットを考える上でも、やはりポイントはあります。

・プロットのポイント

「どの出来事を取り除いても、全体が台無しになるように作る」という名言のようなものがシナリオ界にはあります。
これはつまり、重要でない出来事を極限まで省く事が大事だという話です。

また、個々の出来事がバラバラにあるのは望ましくありません。
因果関係で結ばれた出来事だけで構成していきます。
さらに、それでいて、プロットは自然な、リアルなものでないといけません。
作者の都合で有り得ない展開ばかり繰り返されるようなものは避けるべきです。

キャラクターが意志を持って自然とそう動いていくように誘導していく必要があります。

これらはかなり難しいようにも思えます。
実際難しいです。

という事で、これを目標とはしつつ、最初は自分なりに出来事を並べる所から始めるのがいいでしょう。
逆の事を言うようですが、物語は少しくらい寄り道しているくらいが、余裕があって面白かったりする場合もあります。
もちろんその寄り道にも意味があった方がいいですが。

ここでの結論としては、まずは自分の感性を信じて出来事を並べていき、それから上記の注意に従い、論理的に調整していきましょう。
自分は、ここでの並び替えを簡単に行うため、エクセルのセルに出来事を書いていくスタイルでプロットを進めたりしていました。

5.キャラクター設定・世界設定をしっかりと書く

プロットを書くと、色々キャラクター設定・世界設定に変化が出たり、詳細が決まってきたりします。そういった事柄を、どんどん自分の設定に反映させていきましょう。

6.本文を書く

ついに本文を書きます。
ここは、自分が書きたい物語がマンガなのか小説なのかゲームシナリオなのか、といった所でだいぶ書き方が変わってくる部分もあるので、
詳しくは興味があるジャンルの専門の本を探して読んでもらう形に任せたいと思います。

一つアドバイスをするとしたら、本文をある程度まとまって書いたら、必ず見直しを入れましょう。

これは極めて重要で、バランスが悪くないか、書きたい事が書けているか、内容や文章の間違いや食い違いはないかなど、無数にチェック項目があります。
何度も自分で読み直して、気づいた事をどんどん直していきましょう。

最後に

長々とハウツーのような事を書いてきましたが、正直言って、この世界は「面白いものを書いたもの勝ち」です。
いくらやり方が分かっていても書かなければ意味がないし、やり方が理解できてなくても、とりあえず書き続けていれば、だんだんいい感じに書けるようになったりします。

また、あくまで自分の感想になりますが、感覚の赴くがままに筆を走らせるのは、慣れてくるととても楽しいです。

という事で、陳腐にも思える言葉ですが、「習うより慣れろ」です。
少しでも興味があったら、上記は参考程度に、自分なりのやり方でストーリーを作ってみましょう。
一人でも多くのみなさんが、実際にストーリーを作ってみて、ストーリーを作る楽しさに目覚められるといいなと考えて、自分はこの記事を書きました。

よければ読者のみなさんも、ストーリーづくりにチャレンジしてみてはいかがでしょうか?

そして、さらにそのストーリーをゲームにしてみたいと強く思ったとき、このアピリッツの門戸をくぐってみるのも、面白いかもしれません。

ではでは、お読みいただき有難うございました。

強化学習の基礎

0

AI技術を学ぶ上で理解必須の強化学習の基礎的な内容を数式を使わずに簡潔に説明します。

  • AIに興味がある人
  • 強化学習の基礎的な仕組みを知りたい

という人向けの記事です。

そもそも強化学習とは?

ある環境でエージェントが行動を選択し環境を変化させ、その状態を確認し 最終的に報酬が最も多く得られるような方策を学習します。
まずは単語の意味から説明していきます。

そして今回はイメージがつきやすいように自社ゲームのゴエティアクロスを例に説明します。
その前にゴエティアクロスの説明を簡単にするとプレイヤー(魔導師)と魔神と呼ばれるキャラクター達が協力して敵を倒すゲームです。
魔神にはスキルやレベルがあり、戦闘時は前衛、後衛などの編成を考えながら戦っていきます。
この記事はゲーム紹介の記事ではないので詳しい説明は省きます。

環境

今回はこのゴエティアクロスそのものが環境です。

エージェント

今回はプレイヤー(魔導士)がエージェントになります。

状態

魔神達のHP,レベル,コスト,などです。

行動

ゴエティアクロスでは基本的に敵との戦闘はオートで進行するので出撃させる魔神を変える、レベルをあげる、セットしてるスキルを変更するなどが行動になります。
今回は魔神の編成を変えるだけにします。

報酬

敵を倒す、レアアイテムを取る、短時間でクリアするなどが報酬にあたります。
環境によってはマイナスの報酬もあります。
例えば敵から受けたダメージが大きければマイナスの報酬を与えるなどです。
今回は分かりやすく敵に与えたダメージが前回より多ければ報酬を 少なければマイナスの報酬を与えます。

方策(ポリシー)

方策とは貰える報酬を最大化するために行動ルールです。
今回は敵に与えるダメージを増やすにはどのように編成を変えるべきか?というのが方策になります。

基本的な流れ

単語の意味が一通り分かったところで実際に学習の流れを説明していきます。
強化学習で学習をする際にはゴールが設定されます。
今回はこの深淵の森の受注できる全てのクエストクリアをゴールとします。

エピソード1

環境 水霊、火霊討伐

#01 行動

水霊、火霊討伐から開始します。
エージェントが方策を元に行動。
1回目は敵と戦闘をしていないので編成もランダムで組まれます。

#02 環境の変化

戦闘が終了しました。
これにより現在の環境が
水霊、火霊討伐 → 火霊、氷翼竜討伐に変わりました。

#03 状態の確認

与えたダメージ5828

戦闘したことによってHPなどが減っています。
エージェントはこの時点の与えたダメージと残りHPを確認し前回の戦闘より与えたダメージが多ければ報酬が与えられます。
しかし、逆に前回より与えたダメージが前回より少なければマイナスの報酬が与えられます。

#04 方策の更新

この与えられた報酬を使って方策を更新します。
1回目は前回与えたダメージとの比較ができないので報酬はなしです。
なので方策の更新も行いません。
このまま残りのクエストも進めていきます。

環境 火霊、氷翼竜討伐

与えたダメージ7377
環境 火霊、氷翼竜討伐 → 氷翼竜、白蛇討伐
報酬 なし
方策の更新 なし

環境 氷翼竜、白蛇討伐

与えたダメージ6744
環境 火霊、氷翼竜討伐 → クリア
報酬 なし
方策の更新 なし

ゴール設定は深淵の森の全てのクエストクリアなのでここで1回目の学習は終了です。
この行動開始からゴールまで1ステップをエピソードと言います。
まずはエピソード1終了です。

エピソード2

環境 水霊、火霊討伐

#01 行動

エピソード1と同様に編成はランダムで組まれます。

#02 環境の変化

ここもエピソード1と同じです。

#03 状態の確認

与えたダメージ6096

エピソード1の5828ダメージより多いので報酬を与えます。
エージェントが与えたダメージと残りHPと報酬を確認しているのはエピソード1と同じです。

#04 方策の更新

エピソード2では報酬が貰えたので方策を更新します。
環境 水霊、火霊討伐では今回の編成の方がより多くダメージを与えたので次回の戦闘時ではこの編成が選ばれるように方策を更新します。
このまま残りのクエストも進めていきます。

以降から#02 環境の変化は同じ流れなので省略します。

【環境 火霊、氷翼竜討伐】

#01 行動

#03 状態の確認

与えたダメージ6998


エピソード1では7377ダメージだったので与えたダメージが少なくなってしまいました。
この場合はペナルティとしてマイナスの報酬を与えます。

#04 方策の更新

この編成では与えたダメージが少なくなってしまったので選ばれないように方策を更新します。

環境 氷翼竜、白蛇討伐

#01 行動

#03 状態の確認

与えたダメージ8195

エピソード1の6744より多いので報酬を与えます。

#04 方策の更新

この編成が選ばれるように方策を更新します。
ここでクエストは全てクリアしたのでエピソード2は終了です。
次からはエピソード3です。

エピソード3

【環境 水霊、火霊討伐】

#01 行動

今まではどの編成を組めばより多くのダメージを与えるか分からなかったので
編成はランダムで選ばれていましたが今回からは方策を参考に編成を組めそうです。
水霊、火霊討伐ではエピソード2の編成の方がより多くのダメージを与えることが分かっているのでエピソード2の編成が選ばれました。

#03 状態の確認

与えたダメージ量はエピソード2と同じなので報酬はありません。

#04 方策の更新

報酬がなかったので方策の更新もなしです。

環境 火霊、氷翼竜討伐

#01 行動

エピソード2の編成では与えたダメージが少なくなってしまったのでエピソード1の編成が選ばれました。

#03 状態の確認

与えたダメージ量はエピソード2より多いので報酬を与えます。

#04 方策の更新

この編成が選ばれるように方策を更新します。

環境 氷翼竜、白蛇討伐

#01 行動

エピソード2の編成の方が選ばれました。
#02~#04は環境 水霊、火霊討伐と同じ流れです。
これでエピソード3は終了です。

エピソード4以降でもこれを繰り返し最終的にはどの編成が最もダメージを与える事が出来るか学習していきます。
実際の強化学習では、何もしないと特定の編成ばかり選ばれて他の編成がどのくらいダメージを与えるか試さなくなるので、一定の確率で方策を無視してランダムで行動するというテクニックが使われます。

関連:ゴエティアクロス

GA Next Generation : Google Analytics4

0

In October, Google announced the release of Google Analytics’ new generation: Google Analytics 4. Previously known as “App+Web Property” in its beta version. With this new generation, Google Analytics focused more into the customer journey, so that businesses understand better needs and behavior of their customers.

Why Google Analytics 4?

You might have been confused by why the new generation of Google Analytics was called Google Analytics 4 (GA4). GA4 is the result of the 15 years of Google Analytics’ development, different way of implementation and major changes.

  • 1st generation: Urchin tag (when Google buy Urchin company, urchin.js)
  • 2nd generation: Traditional Google Analytics, the base of the current GA (ga.js)
  • 3rd generation: Universal Analytics, start of cross domain tracking (analytics.js and gtag.js)
  • 4th generation: New Google Analytics 4, with improve analysis and new property default model (gtag.js)

What is Google Analytics 4?

Google new generation analytics is based on the property introduced in beta version last year called App+Web property. With the GA4, the app+web property becomes the default property setting.

The App+Web property is a property enabling the measurement of website, app or both. In last years, mobile users have increased, and the data generated by mobile users cannot be overlooked anymore, while keeping in mind that users might have different devices (PC, tablet…). In Universal Analytics, making data collected from website and app working together was difficult. When the web activity was measured on session-based, app data (Firebase) was measured using an event-based model. With App+Web property and now GA4, both data are unified on event-based model enabling a better and more accurate analysis.

What the differences between Universal Analytics and Google Analytics 4?

1/ Event-based model

From a session-based measurement with UA, GA4 is switching to an event model.

What does it mean? In UA, data was collected into session. During a session (given time frame), Analytics stored user interactions as hits (pageviews, events, eCommerce, social interactions). In GA4, every interaction on the website or app are events. From events, you get to know what is happening in your platforms (pageviews, user actions, clicks, conversion, system events).

To be sure that every tiny or big interactions are collected, GA4 has 3 different types of events:

Events type in GA4

  • Automatically collected events (pageviews, clicks, inApp_purchase)
    • Enhanced measurement for Web data stream
    • Automatic
  • Recommended events:
    • for all website/app : login, purchase
    • specific for your activity (game : level_up, level_start)
  • Customized events (to use when you cannot find any automatic or recommended events that match your needs).

With events, Analytics collects bit of information to specify the event called parameters (3 types as well: automatic, recommended, or customized). Website and app having the same measurement enable you to better understand how users engage with your business across devices and platforms, giving you richer insights.

2/ Full cross-device and cross platform

Being able to identify your users during their interactions with your platform, is very important to understand them better and to develop more accurate marketing ways to target them.

Reports in UA were mainly focused on device-ID (browser cookie), which gave an incomplete view of the user, for example you could not know if the same user was using different platforms. Even if other identification means (User-ID and Google signal) were enabled, the data was collected and viewed in different reports, limiting cross device and platform analysis.

In GA4 and by default, the data is processed by using all available identity information possible. First, by using the User-ID, the ID given by your business from authentication/sign-in method; by Google signal, when the user is signed in its google account and allows its data to be shared; then the device-ID. Despite the default use of all available identification, you can choose to focus on device ID only and ignore any other identification.

In GA4, user identification is key to be able to know how your customer engage with your brand across platforms or devices, and the information is integrated to all reports. You can even create audiences around identified users to better target and personalized their customer’s experiences.

What are the merits of GA4?

1/ Better Analysis tools

a/ Reports

Even if the report panel in GA4 looks mostly like UA, you can get news reports and insights from it. In GA4, reports are newly organized to better focus on the key element of your business: the user and its behavior.

After the Home and Realtime reports, giving you major information about what’s going on your website in general or in Realtime (in the last 5 seconds to 30 minutes), you will have access to the newly organized report category called “lifecycle”. The lifecycle reports enable you to focus on your users during the different stage of its interaction with your website or app: introduction, engagement, conversion, and retention.

New reporting (Google Marketing Platform)

User reports will get all the information you need to know better the user itself: its characteristics (age, country, interests) and the technology they are using to access your platforms.

User Report (Google)

Event reports will focus on every interaction that is happening on your platforms and you will be able to quickly choose your most important interactions/events by making them conversions in a click.

Conversions can be selected from your event list

b/ Analysis tools

The newest category on the panel is the analysis tool! In Analysis, you have all bunches of reports to give you better insights about your business and about what you can improve in your marketing and website so your user can have a better experience while on your platforms.

The first tool is Analysis Hub, where you can create, from scratch or using template, your own report to study what you really need. In a dashboard that looks a bit like Data Studio, you can easily select the dimensions and metrics you want and organize them into various and easy to read graphs. You can add, create your own segment, or compare data between different ones just by clicking and selecting the data you want to use. You can then decide to share or download your masterpiece.               

To analysis your data, you can also choose one of the defined techniques:

  • Exploration > dynamic table layout to enable you to select the metrics you need
  • Funnel analysis or Path analysis > insights about how users are moving around your platforms
  • Segment overlap > how your segments relate to each other and enable you to target very specific audience
  • User explorer > help you personalize the user experience by studying a specific group of users
  • Cohort analysis > analyze the behavior of a group over time on your platform

New Analysis tools in GA4

2/ BigQuery and Google Ad’s stronger connection

In GA4, BigQuery can be linked to your account for free! When you wanted to link UA propriety and BigQuery, you needed to have a 360-account meaning you needed to pay the upgrade of your analytics account. In GA4, it is free!

You will be able to export, collect and store your data in the BigQuery cloud and integrated it with other data sources, or move your GA4’s data to other sources you want to use. You will be able to automatically use the data over to BigQuery pushing even further your analysis.

GA4 and Google Ads are also better connected to automatically update audience to match you user behavior: this user bought a product? Great, Google Ad will not show him the ad to push him to convert anymore. No wasted money and no annoyed customers!

3/ To the future: machine learning and User privacy

While you could get insights using machine learning in UA, the new GA4 gave you new insights and predictions features to make your data work for you. Machine learning can now be used to predict outcomes, trend in demand of a specific products, churn rate (percentage of users that will stop using your services in a given time period), potential revenue by identifying specific segment to focus on high value customers.

In future years, marketers will also have to relate less and less on third party data (cookies from other people than the website you are using), implementing GA4 will help you follow this trend closely as Google said it will start using machine learning to fill out incomplete data resulting from this trend.

GA4 makes it also easier to protect user privacy as well as to comply with the main data control regulation (GDPR, for the European countries with strict control about collecting and storing data from European users; CCPA American regulation). GA4 give you better management tools to collect and retain your data, as well as optimizing or limit the use of it in Google Ads.

How does it work?

So technically speaking, how do you set up the GA4? Well, if you are new to Google Analytics, as GA4 is the new default property, you just have to sign up for an account and fill out the main information, and you will automatically be invited to set up the new property.

Setting up Data stream in GA4

As in the app+web property beta version, when setting the new GA4, you will create data stream: web, iOS or Android. The data stream is the container that received your data. You can have up to 50 data streams for the same property, so if you have a website, and both iOS and Android apps, everything can come under the same property.

When creating the data stream, Google will guide you to tag your website or setting up the app via Firebase new project automatically connected to your account. If you are using Google Tag Manager, you will easily be able to select the two different GA4 tags: GA4 settings for the basic set up (included automatic collected events and enhancement events- pre-setup events for web data stream) and GA4 event to set up recommended and custom events and their parameters.

GA4 tags type in GTM
GA4 tags in GTM are connected to the type of event your platforms use

If you are already using Universal Analytics, you can choose to upgrade to a GA4 property by either create a new GA4 property or connecting to an existing one. This upgrade will not change anything in your UA property, and it will continue to collect data that you can analyze as before. After tagging your website or setting up your app for the new GA4 property, it will start collecting data and you are ready to take advantages of its new features. As it will not change anything for your UA property, it will be clever to start your GA4 property as it may become the norm in the future. This way you will also get to explore the new environment and collect data to be able to analyze future trends from your already accumulated data.

docker上のブラウザで画面キャプチャをとる

0

今回やること

docker上にchromium+ruby+capybaraをいれてキャプチャをとって遊んでみます。
dockerはインストール済みとします。

ソースコードの用意

Dockerfile

FROM ruby:2.7.1-alpine3.12
RUN apk add --update --no-cache \
        g++ \
        libxslt-dev \
        make \
        unzip \
        chromium \
        ttf-freefont \
        chromium-chromedriver

# 日本語フォント
RUN mkdir /noto
ADD https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip /noto
WORKDIR /noto
RUN unzip NotoSansCJKjp-hinted.zip && \
    mkdir -p /usr/share/fonts/noto && \
    cp *.otf /usr/share/fonts/noto && \
    chmod 644 -R /usr/share/fonts/noto/ && \
    fc-cache -fv && \
    rm -rf /noto/*

# 出力用ディレクトリ
RUN mkdir /dist

WORKDIR /app
COPY . /app
RUN bundle config build.nokogiri --use-system-libraries
RUN bundle install
RUN apk del \
        g++ \
        libxslt-dev \
        make \
        unzip
ENTRYPOINT ["bundle", "exec", "ruby", "capture.rb"]

Gemfile

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "selenium-webdriver", "~> 3.0"
gem "capybara", "~> 3.0"

capture.rb

Bundler.require

base_args = %w{--headless --no-sandbox --disable-gpu --disable-extensions --disable-dev-shm-usage --disable-infobars}
Capybara.register_driver :chrome do |app|
  args = base_args.dup << "--window-size=1900,1080"
  driver = Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
      "chromeOptions" => {
        'args' => args,
        'w3c' => false #selenium-webdriver 3系の場合これを付けないとエラーになる
      }
    )
  )
end
Capybara.default_driver = :chrome
browser = Capybara::Session.new(:chrome)
browser.visit ARGV[0]
browser.save_screenshot '/dist/capture.png'

ビルド

docker build -t chrome-capture .

使い方

docker run --rm -v $PWD:/dist chrome-capture https://appirits.com

コマンドを実行したディレクトリにcapture.pngという画像ファイルが作成されて
キャプチャ画像が保存されていれば成功です。

ポートフォリオの作り方・考え方

0

こんにちは。デジタルビジネス部webデザイナーのIです。最近アピリッツへ中途入社させていただきました。
突然ですが、皆さんはポートフォリオ作りは得意でしょうか?周りの方に聞いてもあんまり…といった反応が多いように感じます。
私自身も学生時代に作ったポートフォリオは「作品を並べただけ」と言われてしまい、どう改善をしたら良いのか苦戦しました…

つい苦手に感じて後回ししてしまいがちなポートフォリオですが、新卒の方ですともう半年もしない内に就活が始まるので余裕を持って後悔のないように準備を進められるよう、今回はポートフォリオの作り方・考え方についてご紹介させていただきます。

そもそもポートフォリオって何?

・ポートフォリオ(英語:Portfolio)とは、書類を運ぶ平らなケースの意。
・紙入れ、札入れを意味するイタリア語: portafoglio が語源。

就活においては「作品集」、デザイナー自身を知ってもらうために重要なものです。

作品掲載について 

■作品写真:見せ方は適切か
サイトであればPCやスマホの画面に、ポスターであれば街頭広告に画像を合わせて実際その制作物が使用されている様子が想像できるように加工して載せていました。

■概要:どういった課題があってどのように解決したのか
どういうプロセスで制作を行ったかを書く事で、デザイン的思考ができているかなど自身の考え方について知ってもらう事ができます。

■使用ツール:持っているスキルと会社の業務内容はマッチしているのか
一口にデザイナーと言っても使用ツールは様々です。何を使えるのかを示す事で相手に理解を深めてもらいます。

■制作時間:仕事として制作が出来るのか
どんなにクオリティの高い作品でも、完成するまでに何年何十年とかかってしまうと仕事としては成り立ちません。
そのためどれくらいの期間かかるのか、何時間で完成できるのかなど書いておくと親切です。

■担当領域:何をする人・できる人なのか
複数人で動くプロジェクトに参加した時は自分の担当領域を載せましょう。
ディレクターなのかデザイナーなのかエンジニアなのか、何も書いていないと見る側も判断できかねますし、能力理解にズレが生じる可能性もあります。

全体について

■自己紹介
どんなものが好きなのかや今後どうなりたいのかなど、少しでも自身を知ってもらうポイントを作ります。
面接の時に触れられなくても、読んでもらえる可能性はあるのでチャンスは盛り込みましょう。

■目次
相手は面接に関する書類に目を通す他に通常の業務も抱えている事がほとんどです。
どこに何があるのか、見て欲しいものはどれなのか、案内ができると良いです。

■掲載順
どの業種・会社を受けるのかによって変わります。
私はwebデザイナーとしての応募だったので、制作したサイトの割合を一番多く、手前にしました。
また、こういう事もできますよというアピールをするためにポスターや冊子、果てはデッサンまで後ろの方に入れていました。※バランスには気をつけましょう。

■配慮は足りているか
列は揃っているか、使用フォントや文字の大きさ、色はページ毎にバラバラになっていないかなど。気を付ける点はたくさんあります。
ポートフォリオは全部で一つの制作物という意識を持って、一貫性のある制作をする事が大切です。

■色々な人に確認してもらう
ポートフォリオを見るのはデザイナーだけではないので、色々な人にも見てもらいましょう。
これは就活だけでなくずっと続く課題ですが、多くの人にわかりやすい見せ方を考える事が大切です。

レイアウトはどうしたら良いのか

悩んでいる方はまずポートフォリオが作れるサービスやテンプレートなどを参考にしたり、お気に入りの雑誌などからどう見せると魅力的に見えるのかを考えたりすると良いです。
私は作品が縦でも横でも入れられるような汎用性の高いレイアウトを作ってから、画像や情報を流し込んでいました。

紙とデータはどっちが良いのか

受ける会社によって変わりますが、どちらもあると安心です。
データだと、クラッシュした。ネット環境が悪かった。
紙だと、持ってきたポートフォリオを電車に置き忘れた。不慮の事故で折れた。など…
どのようなトラブルに見舞われるかわかりませんので、どちらも用意して出せるようにするのをおすすめします。

まとめ

改めてポートフォリオを制作した際、下記の2点を意識しました。

1.見る方への分かりやすさと思いやり
2.業種・会社に合わせて何ができるのかを示す

ポートフォリオ作りの考え方はその時だけでなく、日々の業務にも繋がる所が多くあります。
気負いすぎず、まずは1つの作品作りだと思って気軽に取り組んでみてくださいね。

マイグレーション後もDX推進のお付き合いを。クラウドインテグレーション部設立記念、西脇学 × 剣持大介 対談

0

アピリッツは2020年11月1日に「クラウドインテグレーション部」を新設しました。「DX推進のためのクラウドインテグレーション」を謳うこちらの部署の設立背景や展望について執行役員の西脇学とクラウドインテグレーション部 部長の剣持大介がお話します。(2020年10月 取材)

サーバは社員の足元に転がっているほうが安心?

執行役員 西脇学(以下、西脇):クラウドインテグレーション部のお話の前に、雑談がてらちょっと教えてもらいたいのですが、今、クラウド技術の市場はどんな感じですか?

クラウドインテグレーション部 部長 剣持大介(以下、剣持):オンプレミス環境からクラウド環境への移行(=マイグレーション)のニーズが高いです。ただ、監査やセキュリティの観点から二の足を踏んでいらっしゃる企業様も多くいらっしゃいます。

西脇:ああ! わかります! 会社の規模を問わず「サーバが社内のどこかにあるのはOK。でもクラウドはダメです」という企業様は昔から少なくないんですよね。

そういった方に「なぜ社内にサーバがあるのは大丈夫なのですか?」とお尋ねすると、「みんなが見えるところにあるから安心」という答えをいただくんです。これが昔からすごく不思議で。

僕としては、セキュリティの観点から言うと、会社のどこかや担当者の足元でサーバがゴロンと転がってるほうが危ういんじゃないかなと思うわけです。

剣持:一人で何もかも出来てしまうリスクはありますね。

西脇:でしょ? 誰でもさわれちゃうし、目の前にサーバの端末があったら何がどこまでできるかわかっちゃう。だから、クラウドのようにそれぞれの担当者の「できること」を限った状態のほうが、安全性の思想としてはより堅牢だと思いますね

“三菱ショック”から潮目が変わった

―― クラウドへの抵抗もありつつ、それでも新規のお話は全案件クラウドです。やはり流れが変わりつつあるのでしょうか。

西脇:はい。ゲームチェンジがおきたなと肌で感じたのは2017年1月の“三菱ショック”ですね。これは三菱UFJフィナンシャル・グループがAWS(Amazon Web Service)を採用した、って話なんですが、当時国内の、とくに歴史ある企業に衝撃が走ったわけです。

三菱ショック以来「AWSに全力で行きます!」という流れができました。すぐさま“クラウドユーザー向けサイバーリスク保険”が登場したり。

剣持:さらにSIPサーバやVoIP系の機能がクラウド上で使えるようになり、オンプレミスでなくてはならない要因が減りました。これによってAWSに移行しても大丈夫という流れもできたと感じています。

なつかしの三菱ショックを語る西脇さんと剣持さん。

DXの波で「AWSに詳しいからアピリッツに発注する」となった

―― 「クラウドインテグレーション部」を設立したのもそういった流れをうけて、ということでしょうか。いつごろ「部署を作るぞ!」となったのでしょう。

西脇:もともとクラウド導入事業をアピリッツはやってきたのですが、それは、クラウドのみを扱う専門業者としてではなく、アプリケーションを動かすためのものでした。

剣持:「アプリケーションのアピリッツ」、ですからね。

西脇:そうそう(笑)アプリを作って動かすためには土台が必要で、インフラとしてAWSも当然欠かせないよね、技術を磨かないとね、というスタンスで長年やってきました。

ですから、オンプレミス環境からAWSへの移行は、アプリケーションの開発・移行とセットだったんです。大手メディアサイトさんの大掛かりな移行ですとか。

最新のマイグレーションの手法に則って仕事をするので、クラウド導入の経験値もたまります。

やがて「アプリケーションに加えて、とにかくAWSに詳しい人が必要」というご要望を頂戴することが増えました。「アピリッツにはAWSに詳しいエンジニアがいるから」という理由で仕事が発生するんです。

なので、剣持さんや浅田さん(※2020 APN AWS Top Engineers)などベテランのエンジニアたちはそれらのプロジェクトに関わってきました。たとえばAWSの新機能を使う時は浅田さんに必ず入ってもらったり、みんなで解決してきました。

剣持:この流れは2018年頃から予兆があって、2019年には需要の高さがはっきりしました。

西脇:そうだね。で、2020年のDX推進のビッグウェーブが来たわけです。経産省のDXレポートの影響力は大きかった。毎日いろんなDX関連のニュースが出てますよね。補助金が出ますよ、関連銘柄がストップ高ですよ、とか。

結局、ずっとインハウスで抱え込んでいたものをクラウドに載せないと、もう自分たちのビジネスは世の中の変化の速度についていけない、ヤバい、って認識され始めたんですよね。

AWS、GCP、あらゆるクラウド技術を提案する

―― アピリッツでもDX支援のためのデジタル人材を育成していまよね。

西脇:はい。古くからお付き合いのあるAWSはもちろんのこと、アピリッツはGCP(Google Cloud Platform)のパートナー認定も取得しました。

AWSやGCPはこれからも進化していくはずです。技術に対する投資規模がまるで違うのですから、そこを私たちが活用しない手はありません。勉強を続け、お客様のビジネスにとって最適なものを提案できる状態を常に保つ。そういったことがアピリッツの役目です。

……という経緯で、まずは専門チームをかためて育成もする部署を作ることにしました。やっとクラウドインテグレーション部の話になったね!(笑)

剣持:ゆくゆくは、部にとどまらず「アピリッツ全体の仕事のやりかた自体、クラウドインテグレーションが基本」とお客様からご認知いただけるよう進めたいです。

クラウドインテグレーション部にいてほしい人

―― 西脇さんにお尋ねします。剣持さんを部長に選出した理由は何でしょうか。

西脇:まず、古いシステムを扱える経験値があることです。さらにクラウドの経験値もある。マイグレーションって、いわゆるレガシーなものをクラウドに移す場合だってあります。ですから、若い人たちと古いシステムを紐解いて、最新のクラウド技術と適合させていく舵取りにふさわしい人物だと考えました。

剣持:今、世の中では「最初の一歩のDX」の需要が高い。なので、まずは私が「橋渡し」となって、そこをドンと打ち出していきたいです。

西脇:僕らはマイグレーションをやったあとも、DXを進めるお付き合いがしたいです。まずはDXの入り口として必要なことをご提供して、次にやるべきことに対応できるよう備えるのが、私たちの使命だと考えています。

剣持:アピリッツの強みは「Webアプリケーションをワンストップで」提供できる点です。開発、UX/UIデザイン、コンサル、Webマーケティング、すべてをご提供できるのがモットー。これからは「DXをワンストップで」ですね。

西脇:一方で「すべてをモノリスにアピリッツがやる」というのではなく、お客様のオーダーにあわせて、外部の会社さんと一緒にやっていくことも柔軟に考えます。それって「必要なものを必要なだけ」使えるクラウドサービスと似てますよね。

―― クラウドインテグレーション部をどんなチームにしたいですか?

剣持:いろんなサービスやクラウドや基盤の技術があります。それらを最適な形で組み上げられる レゴブロックのように組み合わせられる部署にしたいです。

ですから、一点に詳しいだけじゃなく、いろんな知識を持ち、それらを組み合わせる想像力のあるエンジニアが理想です。

西脇:そうだね。「最初からスクラッチ開発を前提に設計するんじゃなく、これ使えば解決できるんじゃね?」という閃きで突破する人が必要ですね。「あるならもってくる、なければ作る」ってところもクラウドの思想と近いかもしれません。

「そのままのアナタでいて!」と願っている

―― クラウドインテグレーション部が求める仲間のイメージがつきました。他に求めることはどんなことでしょう。

剣持:西脇さんのように「しゃべれる人」ですね。お客様と共に課題に取り組むわけですから、いろんな人を説得する局面があります。

ですから、単にトークスキルが高くて陽気、という意味では当然なくて(西脇・苦笑) 。本質的な理解とアウトプットができることを求めます。お客様のビジネスを損なわないレベルでアウトプットができることは、エンジニアにとって大きな強みです。

―― そういう人はどうすれば育つのでしょうか。

剣持:まずは視野の広さが大切です。面接でもそこを重視します。

西脇:自分の場合は、多能を目指したわけじゃなく垣根がなかった。とにかく、やらない理由や、やらない仕事は作っちゃダメです。

スポーツと一緒だよね。だって、サッカーでフォワードが「俺、キーパーじゃないからキーパーが何する人か知らん」とかありえないでしょ? 全部合わさってサッカーなんだから、全体理解を持った専門性じゃないと。他の仕事を理解しないヤバさってそういうこと。

いつだって垣根のない西脇さん。

IT業界に慣れれば慣れるほど、専門職だから専門外には関わらなくて良い、という傾向になりがちな気がしています。

なぜなら、新卒の研修で彼らにキャリアデザインを書いてもらうと、多くの子は複数のことをやりたがるんですよ。もちろんスペシャリストとして突き抜けていく人は絶対必要ですし、素敵なキャリアですが、そうじゃない人はデザインやマーケティングにも興味を持つ。

もうね、「そのままのアナタでいて!」と思います。それこそが多能の可能性ですから。

アイコと記念撮影。検温と消毒を徹底して働いています。

剣持:我々が目指すのは「クラウドインテグレーション」です。クラウド専門部隊と思われるかもしれませんが、むしろ逆で、「クラウドに持っていく理由を考える」チームです。

お客様と一緒に考え、並走するには、お客様のビジネスやシステムを理解する力と、最適化を考える企画力が必要です。弱点を強みに変えるチャンスを考えて「なんとかする」んです。そこに多能の要素は求められますし、鍛えられます。

DX推進の波を乗りこなし「機を見るに敏に動く」チームにしていきます。

関連記事:アピリッツのその他の役員インタビュー

SaaS業界で「カスタマーサクセス」が重視されている理由を考える

0

自社SaaS型プロダクトのサイト内検索エンジン「Advantage Search」とプッシュ配信CRM「PushTracker」、口コミ投稿管理ツール「VoiceLog」のマーケティングやセールス、本記事でご紹介するカスタマーサクセスの担当をしているWaYです。

現在、SaaS業界で注目されている「カスタマーサクセス」について、重視されている理由を簡単にご紹介したいと思います。

-Chapter1- そもそも「SaaS」とは?

SaaSとは「Software as a Service」の略語で、インターネット経由で各種サービスや機能を提供するビジネスモデルです。
従来は、何かソフトウェアを使う際には自分のPCにインストールすることが主流でしたが、今は自宅のPCからでも全く同じ機能を使うことができますよね。

メールや勤怠管理などのように、実は私たちの身の回りには多くのSaaS型サービスが存在するんです。

「SaaS」のココがすごい!

1.導入が手軽にできる

すでにあるモノを利用するので、一から開発するより導入コストが安くスケジュールも短くなります。

2.手厚いサポートを受けられる

サービス提供会社から常にサポートを受けることができるので、担当者さんも安心してサービスの導入・運用ができますね。

3.最新の機能を常に使える

個人的にはこれが一番アツいと思っています。
サービスのメンテナンスやバージョンアップ含め開発・保守は全て提供会社が行うので、サービス利用者は最新の機能を使い続けることができます。

-Chapter2- 「カスタマーサクセス」って何?

「カスタマーサクセス」とは、何かお問い合わせがあれば回答する”受動的”なサポート体制ではなく、”主体的”に向き合い二人三脚でクライアントのビジネス成長を目指していく考え方を指します。

利用者は高機能で安価なサービスを利用し、提供者はその対価を月額費用として受け取ります。
つまり提供者からすると、そのサービスをより多くの利用者に長く使い続けてもらうことがそのまま利益になるのです。

ただし、今は世の中に様々なSaaS型サービスが普及しているので、そのサービスが「使い続ける意味がない」「有益ではない」と評価されてしまうと利用をやめられてしまいます(=解約)。この”解約”を防止し、利用者のビジネス課題と向き合い続けていくことこそがカスタマーサクセスの最重要課題なのです。

-Chapter3- カスタマーサクセスの存在意義

・クライアントKPIの設計

クライアントがサービスを導入する際、導入作業をサポートするだけではなく導入した後のことも見据えることが重要です。
サービスを利用することで何を目指していくかを設定することが必要となります。

・サービスの活用促進

導入した後、数ヶ月後にはもう使われなくなっている…なんてこともあってはなりません。
より長くサービスを有効活用してもらうためには常にクライアントの利用状況を把握し、よりよい運用のレクチャーや改善提案を行い続けることが重要です。

・クライアントの満足度向上

サービス提供者は、ビジネスパートナーとして課題解決をし続けることで様々な恩恵を受けられます。
解約防止だけでなくアップセルやクロスセルにつながりやすくなり、ひいては他部署や他会社にサービスを紹介してくれることがあるかもしれません。

-Chapter4- カスタマーサクセスの取り組み例

クライアントの満足度向上やプロダクトの有効活用のためにSaaS業界では様々なことが行われています。実際に他社で実際に行われている方法を2つ紹介したいと思います。

1.クライアントが集まるコミュニケーションの場を作る

個人的には、コミュニティを作る、というものが最も印象に残っています。
そこに所属していること自体に価値を感じることができたり、更なる有効活用法などが共有されるとビジネス上のメリットを創出できたりもします。他企業との繋がりを築くことができるのも大きなメリットになると思います。
自社内に専用のラウンジを作ってしまったり、オンラインのコミュニケーションツールへクライアントを招待したりと各社様々な方法で実現しているようです。

2.定期的にアンケートを実施する

全てのクライアントに対し、1年/回、6ヶ月/回、3ヶ月/回などの頻度でアンケートを実施して、満足度を集計するといった取り組みもかなり多く行われています。
そうすることで日頃のやりとりだけではなかなか聞くことができない不満やプロダクトの改善点が見えてきますね。
更にできるだけ回答してもらうために、NPS(※)計測ツールを利用している会社も多いようです。

※:ネット・プロモーター・スコアの略。主にプロダクトやサービスに対する顧客の満足度を計る指標。

最後に

SaaS事業の一番の面白さは、導入・発注してもらうことがゴールではなくむしろそこからがやっとスタートであることだと思っています。
自分たちが企画・開発しているプロダクトを通じてクライアントのビジネスを直接的にサポートし、それを通じてプロダクトも成長することができるのはSaaSでこそ味わえる唯一無二の醍醐味であると言えるでしょう。

私たちSaaSグループは、これからもクライアントのビジネス価値を創出できるよう日々サービスを開発・提供していきたいと思います。

私たちのグループでは、3つのSaaS型プロダクトの企画・開発・保守を行っています。

■自動学習型サイト内検索エンジン「Advantage Search」
 https://search.appirits.com
■CX型プッシュ配信CRM「PushTracker」
 https://push.appirits.com
■口コミ投稿管理ツール「VoiceLog」
 https://voice.appirits.com

新卒ランチ会開催中!~明治神宮前、原宿、表参道付近のおすすめランチ情報~

0

全社会でもお知らせしましたが、現在アピリッツでは20新卒のみなさんに会社付近でランチをご馳走するというランチ会を開催しています!「気軽にコミュニケーションをとれる場がほしい」、「リモートワーク中に入社して、他部署との交流が少ない」などの声を聞き、新卒同期同士の親睦を深めるため企画しました。また、入社してもうすぐ半年ということで仕事で困っていることや悩みなどを気軽に話せる機会になればと思っています。

そこで今回はせっかくなので新卒の皆さんと行った、明治神宮前、原宿、表参道のおすすめの会社周辺ランチをご紹介します!

記念すべき第1回は……

原宿焼肉 KINTAN

食べログ:原宿焼肉KINTANはコチラ

夜はちょっとお高目な高級焼肉屋さんですが、ランチでは1000~2000円で食べられます。また、ご飯、サラダ、スープ、もついていてどれもお替りし放題というバランスとコスパの良さ。最後にデザートまでついてくるので大満足間違いなしです。

みんなから1番人気だった牛タン&KINTAN塩ハラミセット

また、週替わりで期間限定メニューが変わるので毎週通っても飽きません。ランチスタンプが貯まれば2000円オフクーポンが貰えたり、ネットで予約したらドリンク1杯無料という裏技もあります。JR原宿駅寄りなので少し会社から歩きますが気分転換にお散歩がてら行ける距離なので焼肉が食べたくなったら是非行ってみてください♪

続いて……

おばんざい鉢屋

食べログ:おばんざい鉢屋はコチラ

この日は鯖の蒲焼と鶏団子のみぞれ煮、生卵や味海苔もついています。

明治通り沿いを渋谷方面にまっすぐ行くとご飯屋さんしか入っていない通称・飯ビルがあります。(GEMS渋谷)そこに入っているおばんざい屋さんですが、ランチメニューは日替わり定食1種類のみ。平日は850円で香の物・味噌汁・サラダ・おばんざい・コシヒカリごはんお替わり無料という破格的なコスパ。美味しくてバランスもとれてお腹も一杯!メニューを選んだり注文する過程がそもそもないため時間がない日にも便利です。

続いて……

MIZUcafé

食べログ:MIZUcaféはコチラ

上から熱々のチーズをかけてもらいました。

会社から比較的近くて雨の日にもおススメなオシャレなカフェです。名前の通り水にこだわったお店でオランダ発祥のパンネクックという珍しい薄焼きパンケーキが食べられます。

最後に……

しゃぶしゃぶKINTAN

食べログ:しゃぶしゃぶKINTANはコチラ

お出汁の種類も豊富です。

ちょっと会社からは歩きますが、寒くなってきた今にピッタリのしゃぶしゃぶランチです!価格帯は1000円~1500円程度で白米、十六穀米、本日のお惣菜、お野菜、すべてお替り自由で最後に日替りデザートが出てきます。

今回は20新卒限定ランチ会ですが、今後社歴の浅い社員の皆さんや内定者向けにも計画中です!皆さんもぜひ周りの同僚を誘ってランチに行ってみてください♪

最近人気な記事