Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all 21163 articles
Browse latest View live

遊技機開発ならではのノウハウ 【パチンコ】

$
0
0

概要

一般的なゲーム開発と共通する作業が多いと思われる遊技機開発ですが、特有の開発フローや開発手法が多くあります。

私自身、数年前の仕事で複数のパチンコ / パチスロ プロジェクトのメインプログラマー・サブプログラマーを経験しましたが、苦労する事が多くあり、徹夜の残業続きでボロボロになっていました。
昨年のUniteで「Unityでこんなに変わった!ぱちんこ映像開発ワークフロー」を拝聴し、現在では開発フローや手法が効率化され改善されている事に感動しました。

旧来の開発フローや手法ですが、用語の解説も合わせてザックリと紹介します。
※ 秘密保持契約(NDA)に基づき、すでに公開済みのものや独自にないし別ソースから入手されたものなどの紹介です。

Unityでこんなに変わった!ぱちんこ映像開発ワークフロー - Unite Tokyo 2019
https://www.youtube.com/watch?v=fQfpEbEyKro

メインプログラマーとは
仕事内容
は主にパチンコ・パチスロの当り、ハズレを判定するプログラムを設計します。言語はサブプログラマーとは異なり、かなり昔のプログラミング言語であるアセンブラ言語(Z80)を用いてプログラミングします。また、遊技機知識を中心とした法知識は必須となります。

サブプログラマーとは
仕事内容は
パチンコ・パチスロの液晶映像部分のプログラム設計を行います。企画や映像企画が考えたアイデアの実行役としてプログラムの開発を行う仕事です。そのほかに、遊技機開発を効率的に行うための社内開発ツールの制作や出玉設計と連携を図りながら出玉シミュレーターツールを制作するなど幅広い業務を行います。プログラミング言語はCやC++です。

パチンコ開発について

パチンコの開発フローについてまとめます。スマートフォン アプリ開発とは異なり、実機での確認にはかなりの時間がかかる開発フローでした。現在では、Unityの導入でかなり開発効率が上がったようです。

開発フロー

スクリーンショット 2020-03-01 19.16.41.png

企画

パチンコ・パチスロのゲーム性やシステムなどを企画立案します。機種のコンセプトやテーマを企画して、出玉設計やデザイン、サウンドといった幅広い部署と密に連携をとりながら、開発業務全体の全工程を考えます。

出玉設計

パチンコ・パチスロのスペックを算出します。パチンコでいえば大当り確率や確変突入率、大当り時のラウンド振り分け等、出玉仕様をつくりあげることが出玉設計の仕事です。また、パチスロの場合は、ボーナス確率や小役確率の設計はもちろんのこと、プログラマーと一緒にシミュレートすることで数値の微調整を行い正式な数値をつくります。ほかにも、リール配列作成や停止制御作成の業務もあるため、プログラマーとの密な連携が求められる仕事といえます。

サンプル作成


パチンコ・パチスロの企画に基づいた映像演出のアイデアを立案します。アニメ制作のように絵コンテやタイムテーブルなどを作成し、企画や映像制作、サブプログラマーと連携を図りながら作業を進めていきます。

素材作成

サンプルで考えたアイデアを元に、AfterEffectsを使用して、パチンコ・パチスロに使用される画像データを作成します。

図柄表現のつくりかた
第1回 「企画&ベースデザイン」
第2回 「図柄のモデリング」
第3回 「オーサリング(前篇)」
第4回 「オーサリング(中篇)」
最終回 「オーサリング(後篇)」

オーサリングツールについては別でまとめます。

実機化・プログラム

液晶開発、電気回路設計、ランプ制作を作成します。
潜入!SANKYO調査隊!~開発篇~」が分かり易く動画でまとめられています。

潜入!SANKYO調査隊!~開発篇~
https://www.youtube.com/watch?v=mEOyjJy8vNo

実機確認

デバックはもちろんのこと、開発されている機種の仕様チェックや動作確認のために実際に打ち込み検査していきます。

開発基盤

パチンコの主要なLSIについてまとめます。
(もしかしたら、現在は別の物が使用されているかも知れません...)

「AG」シリーズ

「AG」シリーズの強みは、高圧縮・高画質の独自画像コーデックとハイパワーなグラフィックス機能です。現在はそれら機能も強化しつつ、サウンド、LED/モータ制御などマルチな機能をワンチップに統合されています。パチンコ・パチスロ機の演出全体を支えるLSIに進化しています。

参考:
https://www.axell.co.jp/products/list/index.html

「GP」シリーズ

GPシリーズは、パチンコ機、パチスロット機向けのリアルタイムデコード方式のパターングラフィックスVDPです。高性能動画デコーダを搭載し、専用のオーサリングツールを使用することで、効率良くクリエイティブなグラフィックス開発が可能です。

参考:
http://device.yamaha.com/ja/lsi/products/graphic_controller/

オーサリング

制作した映像素材を遊技機に正常に表示させるための映像制作・編集作業をオーサリングと言います。
また、遊技機開発に於いて、制作に最も時間がかかるのは、液晶開発です。

オーサリングツール

遊技機映像を制作するのに必要不可欠な代表的なツールについてまとめます。

Photoshop

adobeのグラフィック編集ソフトで写真の加工、合成の他に絵を描くことも可能なソフトです。
遊技機映像でも図柄制作、テキスト制作、筐体イメージ、等に多くの作業で使用します。

After Effects

adobeの映像加工ソフトで、モーショングラフィックスや、動画映像の加工や合成といった作業に特化したソフトです。複雑なエフェクトの細かい設定ができ、パチンコ・パチスロ遊技機の液晶演出において幅広く利用されています。
拡張プラグインの「Trapcode Particular」で様々なエフェクトを作成することが出来ます。

Maya・3dsMax

遊技機映像は、液晶画面のサイズアップ、表示機能の高性能化に伴い、より一層綺麗でハイクオリティーな3次元的なエフェクト表現が求められるようになりました。Maya・3dsMaxは効率よく3次元的のエフェクト表現を制作できる3DCGソフトです。遊技機でよく行われる版権キャラのCG化は演出用のオリジナルムービー制作に効率がよいです。最近では、セル風アニメ制作にも3DCGソフトが使われています。

ムービーデータの仕組み

ムービーデータは、何枚もの絵がパラパラ漫画のように連続しているものであり、その中の一枚一枚の絵を「フレーム」といいます。
1234098.png
fps(frames per second)フレームレートは、1秒間に何枚の画像を表示するかです。
ムービーデータは「圧縮のアルゴリズム」を使用して、色々な方法で圧縮します。

圧縮のアルゴリズム

主に以下の2種類に分類できます。

  1. フレーム間で似たような部分を圧縮する方法(フレーム間予測) フレーム間にある無駄な情報を圧縮する方法を「フレーム間予測」と言います。
  2. フレーム内の情報を圧縮する方法(フレーム内圧縮) 1つのフレーム内で無駄な情報を圧縮する方法のことを「フレーム内圧縮」と言います。

Iフレーム・Pフレームの違い

「Iフレーム」は、他のフレームを参照しない完全に独立したフレームであり、このフレームのデータだけで再生が可能です。これに対し「Pフレーム」は、直前のフレームから変化した差分のみをデータとして記録しているフレームになります。Iフレームは独立したフレームなので単独での表示が可能ですが、Pフレームは、参照するIフレームなしに表示することはできません。Iフレームが少ないと、部分的情報で済む画像が多くなるので、動画サイズが小さくなります。

まとめ

今回は、遊技機開発ならではのノウハウについて、旧来の開発フローや手法と用語を紹介しました。
また別で、Unityを用いて図柄と変動や演出の実装方法を紹介できればと思います。


入門者もプロもJAMスタックからはじめよう!

$
0
0

JAMスタックとは何か

JAMスタックの公式サイトによると、ビルドが自動か手動か、もしくはフレームワークがNext, Gatsby, Hugoどの種類でも共通しているのはサーバーに依存しないということであると説明されています。ではではJAMの頭文字について説明していきます。

Javascript

上記で「サーバーに依存」しないため、メイン使用することになるのはフロントエンドで大活躍しているJavascriptです。Angular, React, Vueなどのフレームワークやライブラリを使用したものももちろん含まれます。

API

全てのサーバーサイドの処理やデータベースアクションは再利用可能なAPIとして抽象化されており、JavaScriptによるHTTPS経由でアクセスされます。

Markup

デプロイ時に静的サイトの生成ツールやアプリケーションのビルドツールによって事前にビルドされていなければい。

JAMスタックを始めるのは難しいか?

これまで技術構成を表す用語として下記のようなものがありました。

  • MEANスタック(MongoDB + Express + Angular + Node.js)
  • MERNスタック(MongoDB + Express + React + Node.js)
  • LAMP(Linux + Apache + MySQL + PHP)

プログラミングを始めたばかりの入門者が上記のような技術を全て学ぼうとすると、習得にかなりのコストと時間がかかるので、JAMスタックも同様に難しいと思ったのですが、実際に触ってみると、簡単に開発ができ、しかも高パフォーマンスなアプリケーションができてしまうので、エンジニアの転職を考えているかたや、ブログやコーポレートサイトを作ってみたいが「Wordpressか...」なんて思っているかたにかなりマッチするのではないでしょうか。

何から始める?

Javascriptフレームワーク御三家のAngular, React, Vue.jsに対応する静的サイトジェネレータがそれぞれあるので、下記の3つのうちどれかから入るといいと思います。上記3つもそうですが、それぞれの長所、短所があるので、業務で使っているものや実際に書いてみて楽しいものを選ぶのがいいと思います。

1. Scully

GDEのAaron Frostさんらのチームによって開発されたフレームワークです。Angularのサービスや、コンポーネント、モジュールといった概念も使用できるようです。
次に紹介するGatsbyやGridsomeなどの静的サイトジェネレータの人気の高まりを受けて、昨年終わり頃に公開となったため、日本語情報はもちろん、関連記事の絶対数がかなり少ないですが、今後期待が高まるフレームワークだと思います。

2. Gatsby

Reactベースの背的サイトジェネレータです。私はまだ使ったことがないのですが、上で紹介したScullyと次に紹介するGridsomeが、まだまだ日本語の記事やドキュメントが少ないのに対して、わりと記事が充実しているイメージです。

Reactを使い慣れたかたはもちろんですが、3大フレームワークの使用経験がなく、今から静的サイトジェネレータを使いたい人にとってもマッチするのではないかと思います。

3. Gridsome


Vueベースの静的サイトジェネレータです。Page, リンク, コンポーネントなどほぼ全てがVueコンポーネントとなっています。データのやりとりはGraphQLでおこなわれるため、とっつきにくそうに思いますが、一度学んでしまえば素早く開発ができてしまいます。

多くの部分でGatsbyに似ていますが、公式サイトもGatsbyそっくりで、かなりリスペクトがあるみたいです。

日本ではVue.jsやNuxt.jsの採用事例が急激に増えている中で、Gridsomeを使用して手軽にサーバーレスなサイトを作る事例も多くなるのではと思います。

ちなみに私の個人ブログもGridsomeを使用して作成しましたが、かなり早く開発できしていて気持ち良かったです!

まとめ

  • まずはJAMスタックから初めてみよう!
  • 自分にあったフレームワークを選んでみよう!
  • 入門者にもおすすめ。

関連サイト

【ざっくり】コンポーネント指向ってなに?【Vue.js】

$
0
0

はじめに

単一ファイルコンポーネントでの実装を想定してます。
以下のような読者を想定してます。

  • Vue.jsってどういう言語なの?
  • コンポーネント指向?聞いたことはあるけどよくわからん
  • コンポーネント指向はわかるけど、なにが嬉しいの?

コンポーネントとは?

「部品」
「構成要素」
という意味の言葉。

Vue.jsでは、「機能ごとにJavaScriptとテンプレートをセットしたパーツ」のことを指します。
テンプレートは、HTMLとCSSによって構成されます。

ログイン機能のコンポーネントがあるとしたら…

  • JavaScript
    • ログインボタンが押された時、入力されたIDとパスワードを持ったユーザが存在するかチェックする
    • ユーザが存在する場合、ログイン処理を行う
    • ユーザが存在しない場合、エラーメッセージを表示する
  • テンプレート
    • ID入力フォーム
    • パスワード入力フォーム
    • ログインボタン
    • エラーメッセージ表示エリア

みたいな感じになります。

「ログインをする」という一つの機能に対して、必要なものを全てまとめた部品ですね。

コンポーネント指向とは?

たくさんのコンポーネントを作って、それを組み合わせることで一つのアプリケーションを作りあげようという考え方です。

利点

  • 一度コンポーネントにしてしまえば何度でも使える!
    • 違うアプリケーションでも同じものが使える
  • 処理する部分と見た目を定義する部分のソースコードが近い位置にあるから分かりやすい!

単一ファイルコンポーネント

Vue.jsに用意されたコンポーネント指向を助ける仕組みです。
HTML、CSS、JavaScriptを一つのファイルにまとめて書き、拡張子に「.vue」をつけることで単一ファイルコンポーネントの実装ができます。

じゃあコンポーネントごとにJSやCSSを書かないといけないの?というとそういうわけではありません。
「.vue」という拡張子のファイルであっても、今までと同じように外部で宣言された「JSファイル」、「CSSファイル」を読み込むこともできます。
なので、複数のコンポーネントで呼び出されるような汎用的なJS処理、CSSはそれぞれ外部に宣言しておけます。

コンポーネントの使いかた

コンポーネントはHTMLタグのように呼び出せます。

例えばログインコンポーネントであれば
<login />
というように書きます。

また、コンポーネントには値を渡す事ができます。
渡す値によって、同じコンポーネントであっても柔軟な処理を行わせる事ができます。

楽曲の検索機能の実装で例えると
「曲名」を入力させて検索するコンポーネント
<songSearch searchTarget="song_title" />
「アーティスト」を入力させて検索するコンポーネント
<songSearch searchTarget="artist" />
という実装方法になります。

これによって内部の処理を使いまわす事ができ、効率的な開発を行う事ができます。

どんな単位でコンポーネントにすればいいのかわからない…

コンポーネント化の粒度の指標として「アトミックデザイン」というものがあります。
迷ったら参考にしてみるのも良いのではないでしょうか。

参考

コンポーネントの基本 — Vue.js
フロントエンドのコンポーネント設計に立ち向かう - Qiita
基礎から学ぶ Vue.js

AWS ソリューションアーキテクト アソシエイト リージョンとAZ

$
0
0

はじめに

AWSソリューションアーキテクトアソシエイト資格取得のための勉強をアウトプットしていきます。

リージョンとは

大まかに言うと「地域、国」のことです。
AWS は世界中にサーバーを持っており、リージョンという大きな単位でまとまっています。
東京リージョン、ソウルリージョン、北カリフォルニアリージョン、など多数存在します。
AWS リージョン.gif

特徴

複数のリージョンにシステムを分散配置することで、障害耐性を高めることができます。

AZ(アベイラビリティゾーン)とは

各リージョンに、アベイラビリティーゾーンと呼ばれる複数の独立した場所があります。AZ(アベイラビリティーゾーン)とは、物理的、ソフトウェア的に自律しているデータセンタの集合の単位です.
スクリーンショット 2020-03-02 10.12.15.png

抑えておきたいポイント

スクリーンショット 2020-03-02 10.23.18.png

AZ を利用した冗長構成で耐障害性を高める

マルチAZ

複数の AZ を用意しているのは、データセンター障害が発生した場合に対処するためです。AWSをはじめとするクラウドは何もしなくても非常に高い耐障害性を持っているわけではなく、耐障害性が高める複数の仕掛けを用意していることです。
複数の AZ にリソースを分散してリソースを配置することで今回のような単一データセンター障害の場合でも影響を軽減することができます。

例えば ELB を利用して負荷分散する場合は、ap-northeast-1a と ap-northeast-1c にインスタンスを配置するようにします。
また Amazon RDS などのマネージドサービスでもマルチAZ 構成を指定して、別の AZ にリードレプリカを配置し、障害検出時に自動的に切り替えることができます。オートスケーリングを利用する場合でも、複数の AZ を指定して障害時に自動的に、もしくは主導で切り替えることができます。

AWSサービスの3つのサービスレベル

スクリーンショット 2020-03-02 10.59.57.png

最後に

このような感じでポイントを抑えながらアウトプットしていきます。
次はVPCをまとめていきたいと思います。

Kotlin入門:ジェネリック型

$
0
0

ジェネリック型

汎用的なクラス・メソッドに対して、特定の型を紐付けるための機能のこと。

入力例:

valdata:Array=arrayOf(1,2,"3.14")

これに対しジェネリック型を使用すると

//<要素型>valdata:Array<Int>=arrayOf(1,2,3)

こうなります。
これが特定の型を紐付けるということです。

ジェネリック型の定義

classGeneric<E>(varvalue:E){fungetString():E{returnthis.value}}funmain(){valgene1=Generic<String>("Hello")println(gene1.getString())println(gene1.getString()isString)valgene2=Generic(123)println(gene2.getString())println(gene2.getString()isInt)}

①で、GenericクラスにString型を割り当てて代入しています。
これでgene1E型はStringだと判定されるようになります。

②で、GenericクラスにInt型を割り当てて代入しています。
これでgene2E型はIntだと判定されるようになります。
また、<要素型>は省略することもできます。

実行結果は以下の通りです。

Hellotrue123true

型引数の制約

渡す型を制限したいとき、<E:super>の形式で型引数を指定します。
これでE型はsuper、もしくはその派生クラスであるという意味になります。
入力例:

openclassparent(){}
class child():parent(){
    val value = "HelloWorld"
}//E:parentでE型はparentまたはその派生クラスでならなければならないという意味になりますclassGeneric<E:parent>(varvalue:E){fungetString():E{returnthis.value}}funmain(){valgene=Generic<child>(child())println(gene.getString().value)}

ジェネリック関数

引数や戻り値型を、関数を呼び出す際に決められる関数のこと。

構文:

fun<E>name(args:type):rtype{}

E:型引数
name:関数名
args:引数
type:引数の型
rtype:戻り値の型
関数名の直前に<>で型引数を宣言します。

funmain(){println(sayHello("Hello World"))println(sayHello<String>("Hello World"))}fun<E>sayHello(greeting:E):E=greeting

引数の型から、暗黙的に型引数の型を判定するため、特別な構文は不要です。
関数名の直後に<>の形式で型を明示することもできます。
実行結果は以下の通りです。

HelloWorldHelloWorld

【ORDER BY句とLIMIT句】#7 Webディレクター見習いが知識ゼロからSQLを学ぶ

$
0
0

こんにちは!  saku-chanです!
このアカウントは、社会人1年目のWebディレクター見習い(初心者)がSQLを学ぶ成長記録になっています。
ひよっこから成長する過程を残し、ついでに皆さんからアドバイスを頂けたら良いな! 私と同じように知識ゼロからSQLを始める人の一つの指針になればいいな!という思いで作成しました。
ちなみに、ブログを含め記事などを書いた経験がないため読みづらい部分も多々あるかと思いますが、そこも含めて皆さまアドバイス頂けると嬉しいですmm

◆記事の内容は、SQL初心者の自分が、同じような初心者の方でも理解しやすいように心がけながら、SQLの基本に関して学んだことを懇切丁寧に記載しています◆

目次

はじめに

今回はSQLのSELECT文を構成するORDER BY句LIMIT句について勉強したことを記載します!
どちらも簡単なので、さくっといきます!
初めてSQLを勉強する方(プログラミング経験自体がなくてもOK)が気軽に読んでいただける記事になっています^^
ではスタート!

前回の記事【HAVING句】はこちら
前々回の記事【GROUP BY句】はこちら

記事一覧

ORDER BY句とは

ORDER BY句は並び替えのために使用します。

具体例で説明していきますね!

今回使用するテーブルはこちらです。

Table名:quiz_2

numberareateam_namepoints
01東京スマイル2
02大阪たこ焼き3
03東京乃木坂1
04福岡わんちーむ3
05大阪しらんけど7
06東京ガールズ43
07愛知しゃちほこ4

このテーブルに対して以下のクエリを実行すると、

SELECTarea,team_name,pointsFROMquiz_2ORDERBYpointsDESC;

このようにpointsでソートされた結果を得ることが出来ます。

areateam_namepoints
大阪しらんけど7
愛知しゃちほこ4
大阪たこ焼き3
福岡わんちーむ3
東京ガールズ43
東京スマイル2
東京乃木坂1

ちなみに、DESCで降順を指定しています。
なので、もしDESCを記載しないと昇順に並びます。
(ASCと記載しても昇順に並べることが出来ます。)

また、複数のカラムの値によって順番を変更することも可能です!
例えば下記のテーブルを使用してクエリを実行した時、

Table名:quiz_3

numberareateam_namepoints_1points_2
01東京スマイル24
02大阪たこ焼き30
03東京乃木坂13
04福岡わんちーむ35
05大阪しらんけど76
06東京ガールズ432
07愛知しゃちほこ43
SELECTarea,team_name,pointsFROMquiz_3ORDERBYpoints_1DESC,points_2DESC;

以下のように先に記述したpoints_1で降順に並べた後、points_2でさらに降順に並べることが出来ます。

numberareateam_namepoints_1points_2
05大阪しらんけど76
07愛知しゃちほこ43
04福岡わんちーむ35
06東京ガールズ432
02大阪たこ焼き30
01東京スマイル24
03東京乃木坂13



さらに、ORDER BY句WHERE句GROUP BY句とも併用できるんです!
例えばGROUP BY句と一緒に使用した場合を例にあげてみます。

Table名:quiz_2

numberareateam_namepoints
01東京スマイル2
02大阪たこ焼き3
03東京乃木坂1
04福岡わんちーむ3
05大阪しらんけど7
06東京ガールズ43
07愛知しゃちほこ4

上記のテーブルに対してareaごとの平均pointsを知りたい時、下記のようにクエリを記述します。

SELECTarea,    AVG(points)AS平均得点FROMquiz_2GROUPBYareaORDERBY平均得点;

結果は以下の通りです。

area平均得点
東京2
福岡3
愛知4
大阪5

areaでグループ分けし、それぞれの平均得点昇順に並べることが出来ました!

LIMIT句とは

LIMIT句は取得データを制限するために使用します。

Table名:quiz_2

numberareateam_namepoints
01東京スマイル2
02大阪たこ焼き3
03東京乃木坂1
04福岡わんちーむ3
05大阪しらんけど7
06東京ガールズ43
07愛知しゃちほこ4

このテーブルに対して、下記のようなクエリを実行すると、

SELECTarea,team_name,pointsFROMquiz_2LIMIT3;

このような結果を得ることが出来ます。

numberareateam_namepoints
01東京スマイル2
02大阪たこ焼き3
03東京乃木坂1

実際は7レコードあるもののうち、LIMIT句で指定した3レコード分だけを抽出することが出来ています。

テーブルの中身を確認したい時にSELECT句ですべてを指定してしまうと、データベースに負荷をかけてしまうことになるので、LIMIT句を使用して確認することが多いです。

以上です!笑

まとめ

  • ORDER BY句は並び替えのために使用する
  • DESCは降順にしたい時に使用する
  • ORDER BY句WHERE句GROUP BY句とも併用できる
  • LIMIT句は取得データを制限するために使用する

最後に

これで一旦SELECT文に使用される句について全てまとめ終わりました!
次回以降はテーブルの結合やサブクエリなど、引き続きSELECT文に関しての記事を作成していく予定です。
ただ、3月以降忙しくなるため記事作成が滞ると思われます、、><
ではまた次回!

記事一覧

Vue.jsで"this.〇〇 is undefined"と表示された話

$
0
0

経緯

safariでweb開発をしている際に、コンソールにthis.func() is undefinedと表示されていてなんだこれは?となった時の話です。

「methods内にfunc()はちゃんと定義してあるしなあ・・・。」と、vue初心者の僕は何がいけないのかわからず、調べてみました。

簡単な例を用意しました。htmlとjsは以下の通りです。

test.html
<!DOCTYPE html><html><head><metacharset="utf-8"></head><body><divid="app"><button@click="counter">クリック!</button>
        {{ num }}
    </div><script src="https://cdn.jsdelivr.net/npm/vue"></script><script src="test.js"></script></body></html>
test.js
varapp=newVue({el:'#app',data:{num:0},methods:{counter:function(){setInterval(function(){this.num+=1},1000)}}})

22.png
HTMLを表示するとこんな感じになります。

ボタンをクリックすると、ボタンの横の「0」が1秒ごとに1,2,3・・・と増えていきます(実際はエラーが出ます)

何がいけないのか

counter関数内の"this"が原因です。

このthisは、vueインスタンスのthisではなく、setIntervalのthis(window?)を指してしまっています。

対策

setInterval()を呼び出す前に、var th = this;というように記述しましょう。

変更後のjsファイルは以下のようになります。

test.js
varapp=newVue({el:'#app',data:{num:0},methods:{counter:function(){varth=this;setInterval(function(){th.num+=1},1000)}}})

こうすることで、thはvueインスタンスのthisを格納することになるので、numが1ずつ足されます。

ネコと犬の種類判別器を作ってみた

$
0
0

はじめに

わたしは猫さんが大好きです!
機械学習を初めてから一番最初にやりたいと思ったのが猫の種類を当てるモデルを作ることでした。
作ってみたので復習のために書いていこうと思います!
今回はデータセットにわんちゃんも入っていたのでわんちゃんも猫さんも種類を判別できるモデルを作成しました!

データセット

今回、データセットはオックスフォード大学の公開しているデータセットを使用しました
The Oxford-IIIT Pet Dataset

開発環境

・Google Colaboratory

使用したもの

・python3
・Inception V3

モデル作成

まずはいろんなものをimport

cats.ipynb
importtensorflowastffromtensorflowimportkerasimportnumpyasnpfromkeras.utilsimportnp_utilsimportmatplotlib.pyplotaspltimportpandasaspdimportglobfromsklearn.model_selectionimporttrain_test_splitfromkeras.preprocessing.imageimportload_img,save_img,img_to_array,array_to_img,ImageDataGeneratorimportosimportshutilfromPILimportImagefromkeras.applications.inception_v3importInceptionV3,preprocess_input,decode_predictionsfromkeras.modelsimportModel,load_modelfromkeras.layers.coreimportDensefromkeras.layers.poolingimportGlobalAveragePooling2Dfromkeras.optimizersimportAdam,RMSprop,SGDfromkeras.utils.np_utilsimportto_categoricalfromkeras.callbacksimportEarlyStopping,ModelCheckpoint,ReduceLROnPlateau,TensorBoardfromkeras.layersimportInput,Dropout

Google Driveと接続と画像データ準備

Google Driveと接続

データセットが画像で、とても重たいので今回はGoogleDriveにデータを入れてそこから取り出すようにしました
Google Colabでやるととても簡単でスムーズです。
GoogleColabのファイルを開き、ドライブをマウントを押すと「このコードを実行してください」とセルが追加されます。
それに従って認証などを行います。

cats.ipynb
#Google Driveと接続
fromgoogle.colabimportdrivedrive.mount('/content/drive')

zipファイルの解凍

容量が大きいのでzipファイルの解凍もgoogle drive上で行いました

cats.ipynb
#/content/images/がなければ/content/のなかにimages.zipを入れる。
ifos.path.exists('/content/images/')==False:id='....'# 共有リンクで取得した id= より後の部分
downloaded=drive.CreateFile({'id':id})downloaded.GetContentFile('images.zip')else:pass#/content/images/がない時はimages.zipを解凍
ifos.path.exists('/content/images/')==False:!unzipimages.zip#/content/images/があればzipはgoogle drive上で解凍されているので処理は必要ないです。
else:pass

データセットの中の犬と猫の種類をlistに入れる

cats.ipynb
kind_list=['Abyssinian','Bengal','Birman','Bombay','British_Shorthair','Egyptian_Mau','Maine_Coon','Persian','Ragdoll','Russian_Blue','Siamese','Sphynx','american_bulldog','american_pit_bull_terrier','basset_hound','beagle','boxer','chihuahua','english_cocker_spaniel','english_setter','german_shorthaired','great_pyrenees','havanese','japanese_chin','keeshond','leonberger','miniature_pinscher','newfoundland','pomeranian','pug','saint_bernard','samoyed','scottish_terrier','shiba_inu','staffordshire_bull_terrier','wheaten_terrier','yorkshire_terrier']

画像を種類で分ける

今回使用するデータセットが、画像の名前にその画像に写っている子の種類が書いてあるものになります。
ファイル分けなどはされておらず、作成しようとしているモデルの学習には少し使いづらいので、種類ごとにディレクトリを作成して画像を分けることにしました。
先ほど作成したkind_listを使用してディレクトリを作成し、その中に画像を入れていきます!

cats.ipynb
#種類別にディレクトリ作成
#すでにディレクトリがあればpass、なければ作成
forjinkind_list:ifos.path.exists('/content/images/'+str(j)+'/')==True:passelse:os.mkdir('/content/images/'+str(j)+'/')#種別に写真を分けて格納
#画像には種類と番号がふられているので適当な番号(500)で区切ってその番号の名前の画像があれば先ほど作ったディレクトリに移動させる
forjinkind_list:foriinrange(1,500):ifos.path.exists('/content/images/'+str(j)+'_'+str(i)+'.jpg')==False:passelse:shutil.move('/content/images/'+str(j)+'_'+str(i)+'.jpg','/content/images/'+str(j)+'/')#謎のmat形式の画像?をいらないので削除
foriinrange(100,103):ifos.path.exists('/content/images/Abyssinian_'+str(i)+'.mat')==False:passelse:os.remove('/content/images/Abyssinian_'+str(i)+'.mat')

これでデータセットの中の画像を使いやすい状態にすることができました!

データセットの画像をモデル学習用のデータにする

次に、データセットの画像をそのままモデルの学習には使えないので、使える形にしていきます!

cats.ipynb
#画像をリストにarrayにしていれる。ラベルもリストの形で作る
#空の配列を作成
data_img=[]#画像用
kind_label=[]#ラベル用
#リストに入れる際の画像のサイズを指定
img_size=224forjinkind_list:foriinrange(1,300):#画像がなければpass
ifos.path.exists('/content/images/'+str(j)+'/'+str(j)+'_'+str(i)+'.jpg')==False:pass#画像があったら
else:#file_listのなかに画像ファイルのpathを取得
file_list=glob.glob('/content/images/'+str(j)+'/'+str(j)+'_'+str(i)+'.jpg')forfileinfile_list:img_path=file#画像を読み込む
img=load_img(img_path,target_size=(img_size,img_size))#読み込んだ画像をarrayに変換
x=img_to_array(img)#作成したdata_imgのリストの中に入れる
data_img.append(x)#画像の名前の種類の部分をラベルとしてkind_labelのリストの中に入れる
kind_label.append(j)#ラベル(kind_label)をダミー変数に直す
Y_dummy=pd.get_dummies(kind_label)#画像データ(data_img)とラベル(Y_dummy)をtrainとtestに分ける
X_train,X_test,y_train,y_test=train_test_split(data_img,Y_dummy,test_size=0.1,random_state=22,stratify=Y_dummy)

これで、学習データとしての用意が整いました!

モデルを作成する(転移学習)

転移学習

今回はTnsolflowの転移学習モデルInception-v3を使いました。

転移学習とは、学習済みのモデルに、タスク固有のデータを追加で学習させることです。
一般に、少ないデータ数でそれなりに高い精度のモデルが得られると言われています。
また、学習の際に学習済みのモデルの重みは固定し、追加した層のみを使用して学習します。

今回は、様々なカテゴリの画像を学習済みのInception-v3モデルに、猫と犬の画像を追加で学習させて、猫と犬の種類判別に特化したモデルになるようパラメータを調整します。

転移学習の仲間にファインチューニングもあります。
同じと思われがちですが、異なる手法です。
学習済みのモデルを使用した手法であることは同じですが、
ファインチューニングは学習済みのモデルの層の重みを微調整する手法になります。
学習済みモデルの重みを初期値とし、再度学習することによって微調整します。
そこが転移学習とは異なる点です。

モデルの作成

cats.ipynb
#ベースモデルの設定
base_model=InceptionV3(include_top=False,weights='imagenet',input_tensor=None,input_shape=(224,224,3))fromkeras.modelsimportModel#Denseレイヤーを接続
x=base_model.outputx=GlobalAveragePooling2D()(x)x=Dense(1024,activation='relu')(x)predictions=Dense(len(kind_list),activation='softmax')(x)#データの拡張
datagen=ImageDataGenerator(#(True)各チャンネルごとの画素値の平均を0
featurewise_center=False,#(True)サンプルごとの画素値の平均を0
samplewise_center=False,#(True)各チャンネルごとの画素値の分散を1
featurewise_std_normalization=False,#(True)サンプルごとの画素値の分散を1
samplewise_std_normalization=False,#(True)白色化
zca_whitening=False,#ランダムに回転
rotation_range=0,#左右に平行移動
width_shift_range=0.1,#上下に平行移動
height_shift_range=0.1,#ランダムに左右反転
horizontal_flip=True,#ランダムに上下反転
vertical_flip=False)# 転移学習モデル
transfer_model=Model(inputs=base_model.input,outputs=predictions)# 最終段のDenseだけ再学習する
forlayerintransfer_model.layers[:310]:layer.trainable=Falseforlayerintransfer_model.layers[310:]:layer.trainable=True#転移学習したモデルをコンパイル
transfer_model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])hist=transfer_model.fit_generator(datagen.flow(X_train,y_train,batch_size=32),epochs=10,validation_data=(X_test,y_test))#精度確認用に出力
loss=transfer_model.evaluate(X_test,y_test)print(loss)

これを実行すると以下のように学習の様子を見ることができます。学習回数を重ねるごとにlossが減ってaccが上がっているのがわかります
よく学習していてかわいいですね!
データの拡張を多めにしたり、バッチのサイズを変えると精度向上や時間の短縮など工夫することができます
スクリーンショット 2020-03-02 15.49.03.png

モデルの保存

cats.ipynb
#モデル保存用のディレクトリがなければ作成
model_dir='./gdrive/My Drive/model/'ifos.path.exists(model_dir)==False:os.mkdir(model_dir)#モデルを保存
transfer_model.save(model_dir+'model_3.hdf5')# optimizerのない軽量モデルを保存(学習や評価は不可だが、予測は可能)
transfer_model.save(model_dir+'model_3-opt.hdf5',include_optimizer=False)# ベストの重みのみ保存
transfer_model.save_weights(model_dir+'model_3_weight.hdf5')

ここまででデータの学習とモデルの作成は終了しました!

作成したモデルを使用して犬や猫の種類を予測

モデルの読み込み

cats.ipynb
#モデル読み込み
model=load_model(model_dir+'model_3-opt.hdf5',compile=False)

testデータを使用した検証

まずtestデータ30件の画像と正解ラベルを出力してみます。

cats.ipynb
# testデータ30件の正解ラベル
true_classes=np.argmax(y_test[0:30],axis=1)# testデータ30件の画像と正解ラベルを出力
plt.figure(figsize=(16,6))foriinrange(30):plt.subplot(3,10,i+1)plt.axis("off")plt.title(kind_list[true_classes[i]])plt.imshow(Image.fromarray(np.uint8(X_test[i])))plt.show()

スクリーンショット 2020-03-02 16.05.41.png

次に、testデータ30件を予測した予測ラベルと、どれくらいの確率でそのラベルの種類なのか(予測確率)を出力します。

cats.ipynb
# testデータ30件の予測ラベル
pred_classes=np.argmax(model.predict(X_test[0:30]),axis=1)# テストデータ30件の予測確率
pred_probs=np.max(model.predict(X_test[0:30]),axis=1)pred_probs=['{:.4f}'.format(i)foriinpred_probs]# testデータ30件の画像と予測ラベル&予測確率を出力
plt.figure(figsize=(16,6))foriinrange(30):plt.subplot(3,10,i+1)plt.axis("off")ifpred_classes[i]==true_classes[i]:plt.title(kind_list[pred_classes[i]]+'\n'+pred_probs[i])else:plt.title(kind_list[pred_classes[i]]+'\n'+pred_probs[i],color="red")plt.imshow(Image.fromarray(np.uint8(X_test[i])))plt.show()

スクリーンショット 2020-03-02 16.07.02.png
黒い文字で出力されているのは、予測ラベルと正解ラベルが同じだったものつまり、予測が当たったデータ。
赤い文字で出力されているのは、予測ラベルと正解ラベルが違ったものつまり、予測が外れてしまったデータになります。

新しい画像に対する予測

cats.ipynb
#画像を読み込む
img_path=str(input())img=load_img(img_path,target_size=(224,224))x=img_to_array(img)y=np.expand_dims(x,axis=0)#予測
features=model.predict(y)#一番確率が高い種類を取得
pred_classes=np.argmax(features,axis=1)#一番確率が高い種類の予測確率を取得
pred_probs=np.max(features,axis=1)pred_probs=['{:.4f}'.format(i)foriinpred_probs]a=float(pred_probs[0])#予測確率が0.7以下の時はあまり自信がないので似ている種類を出していることにします
ifa<=0.7:print(kind_list[pred_classes[0]]+'に似ています。')else:print(kind_list[pred_classes[0]]+'\n'+pred_probs[0])#読み込んだ画像も出力
Image.fromarray(np.uint8(x))

これで入れた画像に写っているわんちゃんや猫さんの種類を判別してくれるモデルが出来上がりました!!

参考文献

[1]【AI×ねこ】猫の品種を当ててみる
[2]転移学習とは?ディープラーニングで期待の「転移学習」はどうやる?


工場でどこに何人いるのか可視化したい

$
0
0

はじめに

どうやら工場などの作業だと、どこに何人がいるのか分からなくなることがあるらしい。そうなると機械が止まったとしても人員不足によって止まったのか、それとも機械が異常を検知して止まったのか分からなくなるらしい。
なので、工場のどこに何人がいるのかを簡単に可視化させてみようと思う。

工場の配置を作る

工場の初期配置を二次元配置で表現してみます。またそれをcsvファイル(data.csv)に書き込んであとでそのファイルを編集できるようにします。

init_map.py
importcsvlandmap=[[0foriinrange(21)]forjinrange(5)]fori,lineinenumerate(landmap):print(str(i)+":",end="")forareainline:print(area,end="")print()withopen('data.csv','w')asf:writer=csv.writer(f)writer.writerows(landmap)
#実行結果
0:000000000000000000000
1:000000000000000000000
2:000000000000000000000
3:000000000000000000000
4:000000000000000000000

初期配置

イメージとしてはこれを工場で仕事に入る前に持ち場についた時点で作業員にスマホとかで実行してもらう感じです。
まずはdata.csvを数値として読み取ります。
作業員たちに自分がどの場所で作業を開始するのか標準入力を使って入力してもらいます(このコードだとアイウエなど)。
入力してもらった場所の人数を+1する関数を作成します。
関数を使って処理を実行します。
最後にこの処理した内容をdata.csvに書き込んでdata.csvを更新します。

start_arran.py
landmap=[list(map(int,line.rstrip().split(",")))forlineinopen('data.csv').readlines()]importcsva=input('あなたはどこにいますか')defstart_where(s):if'ア'ins:landmap[0][0]+=1elif'イ'ins:landmap[0][5]+=1elif'ウ'ins:landmap[0][10]+=1elif'エ'ins:landmap[0][15]+=1elif'オ'ins:landmap[0][20]+=1elif'カ'ins:landmap[2][0]+=1elif'キ'ins:landmap[2][5]+=1elif'ク'ins:landmap[2][10]+=1elif'ケ'ins:landmap[2][15]+=1elif'コ'ins:landmap[2][20]+=1elif'サ'ins:landmap[4][0]+=1elif'シ'ins:landmap[4][5]+=1elif'ス'ins:landmap[4][10]+=1elif'セ'ins:landmap[4][15]+=1elif'ソ'ins:landmap[4][20]+=1else:print('error')start_where(a)fori,lineinenumerate(landmap):print(str(i)+":",end="")forareainline:print(area,end="")print()withopen('data.csv','w')asf:writer=csv.writer(f)writer.writerows(landmap)
#実行結果
あなたはどこにいますかソ
0:000000000000000000000
1:000000000000000000000
2:000000000000000000000
3:000000000000000000000
4:000000000000000000001

あなたはどこにいますかア
0:100000000000000000000
1:000000000000000000000
2:000000000000000000000
3:000000000000000000000
4:000000000000000000001

あなたはどこにいますかク
0:100000000000000000000
1:000000000000000000000
2:000000000010000000000
3:000000000000000000000
4:000000000000000000001

配置を移動する

工場だと配置を移動することがあることが時々あり、そのせいでどこに何人配置されているのか分からなくなると思うので、持ち場を移動した時の処理を考える。
これまで居た場所の人数を-1して、新しく移動した場所の人数を+1する。

move.py
landmap=[list(map(int,line.rstrip().split(",")))forlineinopen('data.csv').readlines()]importcsva=input('あなたはどこにいますか?')b=input('あなたはどこにいきますか?')defnow_where(s):if'ア'ins:landmap[0][0]-=1elif'イ'ins:landmap[0][5]-=1elif'ウ'ins:landmap[0][10]-=1elif'エ'ins:landmap[0][15]-=1elif'オ'ins:landmap[0][20]-=1elif'カ'ins:landmap[2][0]-=1elif'キ'ins:landmap[2][5]-=1elif'ク'ins:landmap[2][10]-=1elif'ケ'ins:landmap[2][15]-=1elif'コ'ins:landmap[2][20]-=1elif'サ'ins:landmap[4][0]-=1elif'シ'ins:landmap[4][5]-=1elif'ス'ins:landmap[4][10]-=1elif'セ'ins:landmap[4][15]-=1elif'ソ'ins:landmap[4][20]-=1else:print('error')defmove(s):if'ア'ins:landmap[0][0]+=1elif'イ'ins:landmap[0][5]+=1elif'ウ'ins:landmap[0][10]+=1elif'エ'ins:landmap[0][15]+=1elif'オ'ins:landmap[0][20]+=1elif'カ'ins:landmap[2][0]+=1elif'キ'ins:landmap[2][5]+=1elif'ク'ins:landmap[2][10]+=1elif'ケ'ins:landmap[2][15]+=1elif'コ'ins:landmap[2][20]+=1elif'サ'ins:landmap[4][0]+=1elif'シ'ins:landmap[4][5]+=1elif'ス'ins:landmap[4][10]+=1elif'セ'ins:landmap[4][15]+=1elif'ソ'ins:landmap[4][20]+=1else:print('error')now_where(a)move(b)fori,lineinenumerate(landmap):print(str(i)+":",end="")forareainline:print(area,end="")print()withopen('data.csv','w')asf:writer=csv.writer(f)writer.writerows(landmap)
#実行結果
あなたはどこにいますか?ア
あなたはどこにいきますか?コ
0:000000000000000000000
1:000000000000000000000
2:000000000010000000001
3:000000000000000000000
4:000000000000000000001

まとめ

非常に簡単であり汚いコードではあるのですが、工場でどこに何人がいるのかわかるようなプログラミングを描いてみました。

プラスでしたいこと

作業員の各能力を事前に5段階でエクセルなどにまとめておいて、アの位置はhogeの能力が合計N数必要なのでAさんとBさんを自動でアサインする。その結果人数が足りなくてアラートみたいなのが出たら、さらにその場所の必要能力をさらに+Nして人員配置を自動で変更するみたいなアルゴリズムを組めたら面白いなって思います。

初心者から始めるJava、変数と型

$
0
0

はじめに

この記事は備忘録である。
参考書レベルの内容だが、本記事に掲載するコードについては
間違ったものが中心となる。これは実際にコーディング中に間違えた部分を掲載し、自分で反省するために投稿するという目的によるもの。
また、後日にJavaSilver試験問題の勉強を兼ねて復習するため、深い部分の話はここでは触れない。

環境

言語:Java11、JDK13.0.2
動作環境:Windows10

変数とは

変数(Variable)とは、コンピュータが持つメモリを利用して、必要な値を記憶しておくための仕組み。「格納するための箱」として例えられる。

変数を扱うにあたっての必須ルール
1、変数の[名前]を決めて
2、変数の[型]を指定してから
3、変数を[宣言]してから使う

変数の命名に使うことのできる文字・数字の組み合わせを識別子(Identifier)と呼ぶ。ただし、Javaの規則により識別子になれない名前も存在する。

1、識別子のルール

以下は間違った例と、その理由。

Wrong_Identifier.java
1forAll//数字から始めてはいけない。class//javaがほかの用途で使う予約をしている、いわゆる「予約語」all-for^one//特殊文字は使えない。

識別子になれる名前の例も挙げておく。

one4all //頭がアルファベットなのでOK。
classOfOurs //スペースを挟まず予約語以外の言葉になればOK。
all_for_one //アンダーバーで繋がっているものはOK。

2、型のルール

「型」とは「データ型」とも呼ばれ、名前を付けた変数は、その中に格納できる値をあらかじめ定められなければならない。
Javaの基本的な型は後述。ここでは間違えて代入した時の内容を記述する。

Wrong_DataType.java
charmyCatName="テト"//これは文字列、charは文字単体か数字のみ格納bytecharacterLevel=128//byteは-128から127まで格納できる

型によって格納できる中身が決まるのと同時に、型によってコンピュータのメモリをどれだけ使うのかも決まっている。上の例でいえば、charは2バイト、byteは1バイト。最も大きくてもdoubleの8バイトとなる。

3、変数の宣言

Javaにおいて、変数は宣言されなければ使えない。
以下は、変数の宣言と同時に変数に値を格納する初期化(Initialization)で書いたものである。

mistakeOfDeclaration.java
intmoneyInMyPocket=200;intfleshJuice=120;moneyInMyHand=80;//moneyInMyHand変数の型が宣言されていない

最後の一文について、
int moneyInMyHand =moneyInMyPocket - fleshJuice
とちゃんとint型で宣言して書くのが正解。一度宣言された残りの二つについては、型が変わらない限りは再度宣言する必要はない。

変数の代入

変数は他の変数にそのまま代入可能。ただし代入する方・される方の両方の型が同じである必要がある。型の変換を行えば入れることはできるが、ここでは割愛。

Wrong_Assignment.java
intoneMagicNumber=33-4intsimilarMagicNumber=33.4

similarMagicNumberはint宣言をされたが、整数ではなく小数点を含む実数を代入されている。oneMagicNumberには、式の結果である29が格納されている。

スパルタキャンプPython編 2019 Day2 課題

$
0
0

動画上では課題の答えがわからなかったので自分なりに解いてみました。
スパルタキャンプのライブ動画で学習している方の参考になればと思い書きました。

課題

オブジェクト指向プログラミングの初級問題です。
オブジェクト指向を使った良いコードの書き方というよりも、正しい文法で記述できるかを目的としています。

次のコードが正しくなるようなCircleクラスを実装してください。
areaは面積、perimeterは周囲長(円周の長さ)という意味です。

circle.py
#半径1の円
circle1=Circle(radius=1)print(circle1.area())#3.14
print(circle1.perimeter())#6.28
#半径3の円
circle3=Circle(radius=3)print(circle3.area())#28.26 ←恐らく動画での28.27は誤り
print(circle3.perimeter())# 18.84 ←恐らく動画での18.85は誤り
#次のコードが正しく動作するようなRectangleクラスを実装してください
#diagonalは対角線(の長さ)という意味です。
rectangle1=Rectangle(height=5,width=6)rectangle1.area()#30.00
rectangle1.diagonal()#7.81
rectangle2=Rectangle(height=3,width=3)rectangle2.area()#9.00
rectangle2.diagonal()#4.24

答え

雑なコードですが、自分が導き出した答えを参考までに載せておきます

classCircle:def__init__(self,radius):self.radius=radiusdefarea(self):return(self.radius**2)*3.14defperimeter(self):returnself.radius*2*3.14classRectangle:def__init__(self,height,width):self.height=heightself.width=widthdefarea(self):area=self.height*self.widthprint(f'{area:.2f}')defdiagonal(self):line=pow(self.height,2)+pow(self.width,2)line=line**(1/2)print(f'{line:.2f}')

実行結果が以下のようになれば正解!

3.14
6.28
28.26
18.84
30.00
7.81
9.00
4.24

AWS ソリューションアーキテクト アソシエイト VPC偏

$
0
0

はじめに

AWSソリューションアーキテクトアソシエイト資格取得のための勉強をアウトプットしていきます。

Amazon Virtual Private Cloud(VPC)とは

VPC は、AWS アカウント専用の仮想ネットワーク

・任意のIPアドレス範囲を洗濯して仮想ネットワークを構築できる。
・他のVPCと論理的区別される
ポイント
VPCはAZは跨げるが、リージョンは跨げない!

インターネット接続から学ぶVPC

スクリーンショット 2020-03-02 12.10.51.png

VPCの設計

スクリーンショット 2020-03-02 22.22.14.png

IPアドレスとCIDRとは

https://qiita.com/avicii2314/items/380d207a1ad58be27093

ElasticIPアドレスとパブリックIPアドレス

パブリックIPアドレス

・インスタンス起動時に自動的に割り当てられるグローバルIPアドレス。
外部から public DNSに ping して確認が可能。VPC内で変換されるため、インスタンス内ではグローバルIPアドレスは確認できない。(プライベートアドレスのみ)

・インスタンス停止→起動で変わってしまう。

ElasticIPアドレス

Elastic IP アドレスは、動的なクラウドコンピューティングのために設計された静的 IPv4 アドレスです。Elastic IP アドレスは、AWS アカウントに関連付けられます。Elastic IP アドレスを使用すると、アドレスをアカウント内の別のインスタンスに迅速に再マップして、インスタンスやソフトウェアのエラーを隠すことができます。

Elastic IP アドレスは、インターネットからアクセス可能なパブリック IPv4 アドレスです。インスタンスにパブリック IPv4 アドレスがない場合、Elastic IP アドレスとインスタンスを関連付けてインターネットとの通信を有効にすることができます (ローカルコンピュータからインスタンスに接続するなど)。

現在、IPv6 に対する Elastic IP アドレスはサポートされていません。

1.サブネット

EC2インスタンスなどを起動するためのVPC内部に作るアドレスレンジです。
CIDR範囲で分割したネットワークサグメント。
サブネットは必ずいずれかのアベイラビリティゾーンに配置される必要があります。

・サブネットは一つのVPC内では200個まで作成可能。
・サブネット分割範囲は/24、VPCにCIDR /16がおすすめ
ポイント
・サブネットはAZは跨げない、サブネットを選択することはAZを選択すること。
・個々のサブネットは一つの仮想ルータがあり、このルータにはルートテーブルとネットワークACLの設定を持っている。
スクリーンショット 2020-03-02 12.41.01.png
スクリーンショット 2020-03-02 13.09.10.png

2.インターネットゲートウェイとNATゲートウェイ

スクリーンショット 2020-03-02 21.57.29.png

インターネットゲートウェイとは

・VPCとインターネットとの接続するためのゲートウェイです。各VPCに一つだけアタッチ(取り付ける)する事ができる。

パブリックサブネットからインターネットに接続するにはインターネットゲートウェイが必要になる。
・オンプレミスやVPNや専用線で通信するためのゲートウェイをVGW(バーチャルプライベートゲートウェイ)という。

NATゲートウェイとは

プライベートサブネットのインスタンスをインターネット接続するためのゲートウェイ。
パブリックサブネットに配置する!!
・自動的にENI(Elastic Network Interface)がアタッチされる。
*ENIとは
仮想的なプライベート環境にEC2を使ってサーバーを立ち上げることができます。こうした環境において、VPCに対してネットワークインターフェースを追加する役割を担うのがENIです。ENIは、物理的な環境におけるNIC(Network Interface Card)のことです。

セキュリティグループとネットワークACL

セキュリティグループ

・EC2やELB,RDSなどインスタンス単位の通信制御に利用する。
・通信の制御として、インバウンド(内向き、外部からVPCへ)とアウトバウンド(外向き、内部から外部へ)の両方の制御が可能。プロトコルやポート範囲、送受信先のCIDRかセキュリティグループを指定できる。

・ステートフルなファイアウォールのこと。デフォルトで許可されているのは同じセキュリティグループ内通信のみ(外からの通信は禁止)。そのため例えば、WEB公開する場合はインターネット(0.0.0.0/0)から80ポートを許可する。
スクリーンショット 2020-03-02 19.46.40.png

ネットワーク ACL

・ステートレスなファイアウォールのこと。サブネット単位で適用され、デフォルトでは全ての送信元IPを許可する。
・明示的にトラフィックを設定しないと通信遮断してしまう。
スクリーンショット 2020-03-02 22.05.45.png

ポイント
・前後の状態に依存しないのがステートレス(stateless)で、前後の状態を保持しているのがステートフル(stateful)という意味
・セキュリティグループはインスタンス範囲の通信制御!
・ネットワークACLはサブネット範囲の通信制御!
スクリーンショット 2020-03-03 10.25.10.png

比較

スクリーンショット 2020-03-02 19.47.03.png

VPCエンドポイント

スクリーンショット 2020-03-02 22.14.37.png

VPC エンドポイントでは、AWS PrivateLink を使用する、サポートされている AWS サービスや VPC エンドポイントサービスに VPC をプライベートに接続できます。

インターネットゲートウェイ、NAT デバイス、VPN 接続、または AWS Direct Connect 接続は必要ありません。VPC のインスタンスは、サービスのリソースと通信するためにパブリック IP アドレスを必要としません。VPC と他のサービス間のトラフィックは、Amazon ネットワークを離れません。

エンドポイントは仮想デバイスです。これらは水平にスケールされ、冗長で、可用性の高い VPC コンポーネントです。これにより、ネットワークトラフィックに可用性リスクや帯域幅の制約を課すことなく、VPC 内のインスタンスとサービス間の通信が可能になります。

VPC エンドポイントには 2 種類あります。インターフェイスエンドポイントゲートウェイエンドポイントです。サポートされるサービスにより要求される VPC エンドポイントを作成します。

インターフェイスエンドポイント
スクリーンショット 2020-03-02 22.15.47.png

ゲートウェイエンドポイント
スクリーンショット 2020-03-02 22.15.55.png

比較

スクリーンショット 2020-03-02 22.16.05.png

VPC Flow Logsとは

VPC Flow Logsはネットワークトラフィックを取得しCloudWatchでモニタリングできるようにする機能
スクリーンショット 2020-03-02 22.52.37.png

VPCとプライベートネットワーク(オンプレミス)接続

スクリーンショット 2020-03-02 22.25.21.png

スクリーンショット 2020-03-02 22.39.25.png

Direct Connectとは

クライアントのデータセンターやオフィスの専用線などを介してAWSへプライベートに接続するサービス!

メリット

・安価なアウトバウンドトラフィック料金
・ネットワーク信頼性向上
・ネットワーク帯域幅の向上

仕組み

Direct Connectロケーションに物理的に自社オンプレ環境を接続する事でAWS環境との専用接続線を実現する。

Direct Connect gateway

Direct Connect GatewayがHubになり、同一アカウントに所属する複数のリー ジョン複数のロケーションから複数リージョン複数のVPCに接続できる機能。
・簡単にいうとリージョン間のネットワーク接続がリージョン間をまたいでできる!!
スクリーンショット 2020-03-02 22.43.43.png

VPNとの比較

スクリーンショット 2020-03-02 22.47.10.png

VPC Peering

VPC Peeringにより2つのVPC間でのトラフィックルーティングが可能
スクリーンショット 2020-03-02 22.57.57.png

VPC設定上限

スクリーンショット 2020-03-02 22.54.36.png

最後に

今回はイメージしやすいようにBlackBeltをたくさん参考にさせていただきました!
次回は、IAMについてまとめていきたいと思います!

Mac に Node.js 環境をさくっと整えるための最短ルート

$
0
0

Mac を買った

  • 新しい MacBook Pro を買った
  • というわけでアプリとか作ってみたいし JavaScript とかをガンガンやっていきたい
  • いろいろ調べたところ・・・
  • アプリ開発にあたって Node.js とかいうやつをインストールする必要が出てきた
  • でも買ったばっかりだから Mac の中身からっぽじゃん。。
  • 「Mac Node.js 環境構築」、検索と
  • 「nodebrew」「nvm」「anyenv」「nodenv」「ndenv」「npm」「yarn」・・・
  • :smiley:・・・
  • 俺はアプリ開発を諦めた
  • となりかけたので、改めて、空っぽの Mac に Node.js まわりの環境を整えるまでをメモ。

この記事で扱うこと(使えるようになるもの)

  • 何も入っていない状態の Mac に Node.js のバージョンマネージャとパッケージマネージャをインストールして、Node.jsを用いた開発に着手できる環境を構築する
  • 扱うものは以下。
    • Homebrew
    • anyenv
    • nodenv
    • yarn
  • これらのうちどれかを単体で扱った記事(そのぶん詳しく書かれているので有難いですが)や、それぞれの他の選択肢との比較記事(例: nodenv vs nvm, yarn vs npmなど)が多いような印象のなか、本記事は「とりあえずコードを書ける状態まで持っていきたいんだけど、、」という方向け(そういった比較記事も読んだうえで、わりと評判のよいものたちを選んだつもりです)。

環境

  • macOS Catalina 10.15.3
  • MacBookPro (16inch, 2019)

1. Homebrew のインストール

  • Homebrew の公式サイトに、「このスクリプトをターミナルに貼り付け実行して下さい。」と書いてあるのでコピーしてターミナルに貼り付け実行する。 スクリーンショット 2020-03-02 19.05.59.png

2. anyenv のインストール

anyenv とは (GitHub へのリンク)

  • 「○○env」と名のつくものたち(今回使う後述のnodenvや、たとえばPythonで使うpyenvなど。主に、プロジェクトごとに言語のバージョンを簡単に切り替えるために使ったりする)をまとめて管理する便利なやつ。
  • 今回は JavaScript (Node.js) だが、のちのち別の言語でも開発してみるとなったときにも便利。

anyenv インストール手順

  1. 上でインストールした Homebrew を使う。ターミナル(私の場合zsh)で以下を実行。

    ターミナル
    $brewinstall anyenv
    
  2. 続けて、ターミナルで以下を実行。

    ターミナル
    $anyenv init
    
  3. そうすると、指示が出てくるのでそれにしたがって、 ~/.zshrc(bashの場合は~/.bashrc) に eval "$(anyenv init -)"と追記する。具体的には以下のとおり。

    ターミナル
    vi ~/.zshrc
    
    .zshrc(bashの場合は.bashrc)に追記
    eval "$(anyenv init -)"
    
  4. ターミナルを再起動

  5. ターミナルを再起動したタイミングでWarningが出てくるので、指示通りに以下を実行

    ターミナル
    $anyenvinstall--init

nodenvのインストール

nodenv とは (GitHub へのリンク)

  • Node.js のバージョン管理に使う。
  • プロジェクトごとに Node のバージョンを簡単に切り替えることができる(たとえば、昔作ったアプリAはちょっと古いバージョンだけど、新しく作るアプリBでは最新バージョンのNode.jsを使う、など)。

nodenv インストール手順

  1. 上でインストールした anyenv から nodenv をインストール。

    ターミナル
    $ anyenv install nodenv
    
  2. ターミナルで以下を実行(起動中のシェル($SHELL)をログインシェルから起動させるコマンド)

    ターミナル
    $ exec$SHELL-l
  3. 続いて、ターミナルで以下を実行することで、インストール可能なNodeのリスト(一覧)が出る。

    ターミナル
    $nodenvinstall-l
  4. その後、インストールしたいバージョンを指定(以下の例では12.16.1)してターミナルで以下を実行。

    • 最新の安定バージョン(LTS; Long-Term Support)や最新版は Node.js の公式サイトから確認できる。
    • 特にこだわりや制約がないのであれば、LTSとなっているバージョンを指定すればよい。
    ターミナル
    $nodenvinstall 12.16.1
    
  5. 続いて、以下をターミナルで実行。

    ターミナル
    $nodenv rehash
    
  6. 最後に、以下のコマンドをターミナルで実行することで、インストールしたバージョンの Node.js を使えるようになる

    ターミナル
    $nodenv global 12.14.0
    
  • ちなみに、個別のプロジェクト(アプリ)でバージョンを切り替えたい場合は、まず、利用したいバージョンをインストール($nodenv install (バージョン番号)してから、そのディレクトリ内で$nodenv local (バージョン番号)と打って実行することで、プロジェクトごとにバージョンを切り替えることができる。

yarn のインストール

yarnとは

  • JavaScript のパッケージマネージャ
  • npm(これも超有名なパッケージマネージャ)と互換性があるが、npmよりもインストール速度が速いなど、npmよりも高性能だと言われている
  • JavaScriptでの開発時にはほぼ必須となるはずなのでこのタイミングでインストールすべし
  • 詳しい使い方は 参考記事の 4, 5 などが参考になる。

ターミナルで以下を実行し yarn をインストール

ターミナル
brew install yarn

環境構築完了!

Enjoy JavaScript!

参考記事

  1. Mac に anyenv でサクッとマルチ開発環境構築
  2. anyenv から入れた nodenv で Node.js を入れたときのメモ
  3. anyenv と nodenv で node.js バージョン管理、設定後に gulp の設定を修正(Mac)
  4. 使い方(yarn公式ガイド)
  5. npmとyarnのコマンド早見表

Mac XAMPPを用いてPHPのローカル開発環境を整える

$
0
0

目的

  • PHP7.4のローカル開発環境の整え方をまとめる
  • 環境構築を優先しその他の作業は誰でも理解できるような方法で進める
  • ApacheとMySQLを使用して構築する

余談

  • MacはXAMPPではなくMAMPを使うらしい

実施方法概要

  1. XAMPPのインストール
  2. ApacheとMySQLの起動
  3. テスト

実施方法詳細

  1. XAMPPのインストール
    1. 下記サイトにアクセスする。
    2. XAMPP for OS Xの「7.4.2 / PHP 7.4.2」の「Download(64bit)」をクリックする。 スクリーンショット 2020-02-28 22.34.11.png
    3. 画面が切り替わり、ダウンロードが開始されるので完了するまで待機する。 スクリーンショット 2020-02-28 22.34.41.png
    4. Downloadフォルダを開きダウンロードしたインストーラ「xampp-osx-7.4.2-0-vm.dmg」を開く。 スクリーンショット 2020-02-28 22.48.22.png
    5. 下記のウインドウが開いたらXAMPPのアイコンをドラックしてアプリケーションフォルダに移動する。 スクリーンショット 2020-02-28 22.49.54.png
    6. アプリケーションフォルダを開きXAMPPのアイコンをクリックして起動する。 スクリーンショット 2020-02-28 22.52.35.png
    7. 下記のウインドウで「開く」をクリックする。 スクリーンショット 2020-02-28 22.53.01.png
    8. 初回インストールなので管理者権限が必要になるウインドウが開くので「OK」をクリックする。 スクリーンショット 2020-02-28 22.54.43.png
    9. 下記のウインドウが開いたら現在のアカウントにログインする時のパスワードを入力する。 スクリーンショット 2020-02-28 22.55.32.png
    10. DockのXAMPPのアイコンをクリックして下記のウインドウが表示されればXAMPPのインストールは完了である。 スクリーンショット 2020-02-28 22.57.10.png
  2. ApacheとMySQLの起動
    1. XAMPPを起動して下記の画面が開いたことを確認する。 スクリーンショット 2020-02-28 22.57.10.png
    2. 「Start」をクリックしたあとStatusが一旦黄色になることを確認し待機する。 スクリーンショット 2020-02-28 23.19.57.png
    3. ウインドウが変化し、Statusが緑色になりIP Addressが表示されことを確認する。 スクリーンショット 2020-02-28 23.23.08.png
    4. Serviceのタブを開く スクリーンショット 2020-02-28 23.26.36.png
    5. 「Restart All」をクリックし待機する。Apache MySQL ProFTRDのステータスが一時的に黄色に変化する。 スクリーンショット 2020-02-28 23.27.20.png
    6. Apache MySQL ProFTRDのステータスが緑色になったことを確認する。 スクリーンショット 2020-02-28 23.28.50.png
  3. ネットワーク設定
    1. XAMPPのNetworkタブを開く スクリーンショット 2020-02-29 0.35.39.png
    2. localhost8080 -> 80(Over SSH)を選択し「Enable」をクリックし、ステータスが緑色になったことを確認する。 スクリーンショット 2020-02-29 0.36.41.png
  4. マウント設定
    1. XAMPPのVolumesタブを開く スクリーンショット 2020-02-29 0.22.55.png
    2. 「Mount」をクリックする。 スクリーンショット 2020-02-29 0.23.32.png
  5. テスト

    1. 「Explore」をクリックする。
    2. 下記のようにフォルダが開く。 スクリーンショット 2020-02-29 0.24.14.png
    3. htdocsフォルダの中にprojectフォルダを作成し、hello_world.phpとというファイルを作成する。 スクリーンショット 2020-02-29 0.27.12.png
    4. hello_world.phpをテキストエディタで開き下記の内容を記載する。

      <?phpecho"hello world";?>
    5. 下記にアクセスしてhello worldが表示されているか確認する。

    6. 下記のように表示されていれば環境構築完了である。
      スクリーンショット 2020-02-29 0.37.49.png

仮想マシン上のWindows10 HomeでWSL2を体験したい

$
0
0

はじめに

普段WSL1やVMware Workstation Player上に構築したLinuxをちょこっと触ったりしています。
そんな中、次期バージョンのWSL2ではDockerがインストールできるということで興味があるのですが、プレビュー機能のため利用してみたい場合はWindows Insider Programを導入する必要があるとのこと。
Windows Insider Programは評価版のWindowsが導入されるとのことで、普段使いのPCには導入をためらっていました。

そこで未使用のWindows10 Homeエディションを使って、VMware Workstation Player上にWSL2を導入できないか試してみました。

簡単なまとめ

  • Windows Insider Programのビルド種類ですが、2020/03/03時点では、WSL2のみを使う目的であれば安定性の面で「ファスト」よりも「スロー」をおすすめします 1
  • WSL2がHyper-Vの機能を利用する関係上、VMware Workstation Playerの「Intel VT-x/EPT または AMD/RVI を仮想化」を有効化しないと動作しません。
  • 仮想環境へのメモリ割り当ては最低6GB欲しいところです 2

検証環境

ホスト側

  • Windows10 Pro バージョン1909 64bit
  • CPU:Intel Core-i5 2540M
    • ハードウェア仮想化支援機能として「VT-x」「VT-d」が利用可能
  • メモリ:16GB搭載

ゲスト側

  • VMware Workstation Player 15.5.1
    • Windows10 Home側にVMware Tools for Windows (11.0.0) をインストール済み
  • Windows10 Home バージョン1909 64bit
  • メモリ:6GB割り当て
  • ストレージ:60GB割り当て

導入手順

仮想化ソフトウェアに「VMware Workstation Player」を利用し、その上でWindows10 Homeが導入済みという前提になります。
※前提の導入手順は省略いたします。

  • PCのBIOSまたはUEFIの設定で、ハードウェア仮想化支援機能を有効化します。

    • Intel CPUの場合は「VT-x」の有効化が必須です。
  • ゲスト側の仮想マシンを停止した状態で、VMware Workstation Playerの「仮想マシン設定」を開き、「ハードウェア」→「プロセッサ」の項目で「仮想化エンジン」の設定を有効化します。

    • Intel VT-x/EPT または AMD/RVI を仮想化 ※必須
    • CPU パフォーマンス カウンタを仮想化 ※お好みでOKかと。
    • IOMMU(IO メモリ管理ユニット)を仮想化 ※Intel VT-dが有効の場合は、チェックを入れても良いかと。
  • 設定を保存し、ゲストの仮想マシンを起動します。

  • ゲストの起動後、「スタート」メニューの「設定」から「更新とセキュリティ」→「Windows Insider Program」をクリックします。

  • 画面表示に従って手続きを進め、「Insider の設定を選択」画面で「スロー」を選択します。

  • 「Windows Insider Program」への登録完了後、ゲストの再起動を行います。

  • 「Windows Update」を実行し、バージョン2004を導入します。

  • ゲストのコマンドプロンプトを起動し、「winver」と入力してEnterキーを押下し、「Windows のバージョン情報」ダイアログからOSビルドが「18917」以降であることを確認します。

  • ゲストにおいて管理者権限でPowerShellを起動し、以下のコマンドを実行します。
    または、「Windows の機能の有効化または無効化」画面より、以下の2つにチェックを入れます。

    • Linux 用 Windows サブシステム
    • 仮想マシン プラットフォーム
PowerShell
dism.exe/online/enable-feature/featurename:Microsoft-Windows-Subsystem-Linux/all/norestartdism.exe/online/enable-feature/featurename:VirtualMachinePlatform/all/norestart
  • ゲストを再起動します。
  • ゲストのMicrosoft StoreよりWSL用のディストリビューションをダウンロードします。
    • 既にWSL1のディストリビューションを導入済みの場合、PowerShellにてWSL2に変換します。
    • 初めてダウンロードする場合、PowerShellで設定することで、デフォルトをWSL2形式にすることができます。

以下のコマンドについては、管理者権限は不要です。

PowerShellでWSL1をWSL2に変換する例
# 導入済みのディストリビューションを確認します。wsl-l-vNAMESTATEVERSION*Ubuntu-18.04Stopped1# 以下のコマンドでWSL1をWSL2に変換します。環境によりある程度の時間がかかります。wsl--set-versionUbuntu-18.042
PowerShellでデフォルトにWSL2を指定する
wsl--set-default-version2# 以下のコマンドでデフォルトをWSL1に戻すことができます。wsl--set-default-version1
  • 変換後またはダウンロード済みのディストリビューションを開いて、問題なく動作することを確認します。

ハマった点など

  • ゲスト側のWindows10 Homeで、「Microsoft Defender」以外のウィルス対策ソフトが動作している場合、WSL2への変換や起動が行えない可能性があります。
    • ゲスト側にてavastを動作させていたところ「エラー 0x80370102」が発生して、WSL2をどうやっても起動または変換できませんでした。avastをアンインストールすると解決しました 3

その他

WSL2のUbuntu (無印版:バージョンは18.04.4) にDockerを入れてみましたが、通常のLinuxへの導入と同じ方法で簡単に入れることができて感動しました。
また、VS CodeのRemote - WSL機能拡張も問題なく動作しました。

一方、2020/03/03時点ではDocker Desktop WSL2 BackendがWindows10 Home環境にインストール出来ないため、VS CodeのRemote - Containers機能拡張は使えないようでした。こちらは今後に期待です。

仮想環境としてVMware Workstation Playerを使っている関係上、WSL2が正式リリースされた場合はホスト側で同居できなくなりそうですが、VMware様側でWSL2と同居可能なバージョンを開発しているみたいなので、こちらも今後に期待です 45

参考サイト様


  1. ファスト導入時に文字化けが発生したりしたため、自分の環境では厳しいと判断しました。 

  2. 起動直後で2.6GB程度、ブラウザ・VS Code・WSL2を起動で3.6GB程度メモリを消費していました。 

  3. avastの設定より「ハードウェア仮想化支援機能を有効にする」のチェックを外すと動作する、という情報も見たのですが、自分の環境では問題が解消しませんでした。 

  4. 現時点ではIntel 第4世代以降のCPUが対象のようですが、第2・3世代のサポートも検討しているとのことです。 

  5. 製品エディションはWorkstation Pro版が対象のように見えますが、無償版にも対象を広げてもらえることを期待しています。 


【初心者】PHPでカレンダー出力のプログラミング

$
0
0

どうも、UT(@ut_1029)です。ブログ(UTの日常)の紹介です。

PHPでカレンダーをプログラミングしたサンプルコードを紹介します。

PHPでカレンダーのプログラミング

<?php$weeks=[0=>'日',1=>'月',2=>'火',3=>'水',4=>'木',5=>'金',6=>'土',];$today=date('Ymd');$start=date('Ym01',strtotime($today));$tmp=date('Ym01',strtotime($start.' +1 month'));$end=date('Ymd',strtotime($tmp.' -1 day'));$days=[];$len=0;for($day=$start;$day<=$end;$day++){$w=date('w',strtotime($day));if($w==0){$len++;}if(!isset($days[$len])){foreach($weeksas$key_week=>$val_week){$days[$len][$key_week]='';}}$days[$len][$w]=$day;}?><html><head><metacharset="UTF-8"><title>PHPでカレンダー</title></head><body><h1>PHPでカレンダーを作成</h1><div><?phpechodate('Y年n月',strtotime($today))?></div><table><thead><tr><?phpforeach($weeksas$key_week=>$val_week):?><th><?phpecho$val_week?></th><?phpendforeach;?></tr></thead><tbody><?phpforeach($daysas$day):?><tr><?phpforeach($weeksas$key_week=>$val_week):?><?php$style='';if($key_week==0){$style='color: red;';}elseif($key_week==6){$style='color: blue;';}?><?phpif($day[$key_week]):?><tdstyle="text-align: right;<?phpecho$style?>"><?phpechodate('j',strtotime($day[$key_week]))?></td><?phpelse:?><td></td><?phpendif;?><?phpendforeach;?></tr><?phpendforeach;?></tbody></table></body></html>

解説は、ブログ(UTの日常)で!

【初心者】PHPでカレンダー出力のプログラミングを解説 | UTの日常

IBM CloudのDb2をスケールさせる

$
0
0

はじめに

「IBM CloudのDb2をスケールさせる」って言うとカッコ良く聞こえますが、単にDisk容量を増やしただけの記事です。ですが手順、表示される実画面、処理時間など、実際やってみると、「気づき」がありましたので共有させてください。

クラウドなのにDiskが一杯?

事の起こりは下図のような「SQL0968C ファイルシステムがいっぱいです。SQLSTATE=57011」エラーが始まりでした。
SQL0968C_20200226.png

クラウドなので容量不足になるなんて思っていませんでした。私が使っているIBM CloudのDb2 Flexプランには「¥102.00 JPY/GB of Storage (for each node)」と書いてますが「容量が不足したら自動的に1GB単位102円で増加します」とは書いていません。自分で明示的に増やす必要があると分かると以下のような記述がすぐに見つかりました。
0.ScaleServiceInstance.png
2GB,10GB,25GB,50GB,100GB,150GB,250GB,500GB,1TB,2TB,4TB単位で増やせる(増やさないと一杯になる)わけです。自動的容量が増えると勝手に解釈していた「おめでたい」自分が恥ずかしくなりました。

Scale Instanceメニューを使う

明示的に自分で増やさないとイケない・・と思うと、今まで見えていなかった管理画面の「Scale Instance」の文字がドーーンと目に入ってきました。
0.ScaleInstance.png

上図の「Scale Instance」をクリックすると、下図のようにストレージが2GBしかない事が分かります。これを右側に引っ張って10GB,25GB,50GB,100GB・・・と増やすします。

1右に引っ張る.png

10GBにすると2GBの時19300円/月だったのが20116円/月となりそうです。
「Choose Timeline」で「Immediate」を選択して即時適用としてみました。
2.chooseTimeLine.png

確認画面が表示されるので「Notification Email」にメールアドレスを入れて「Confirm Request」をクリックします。
3.RequestToScaleInstance.png

下図のように「Success」表示されるまでドキドキしながら20分程度要しました。
6.Success.png

反省

クラウドは「使ったら使った分だけ支払う」のような営業トークを技術的な設定と混同してしまいました。あえて言うなら「契約したら契約した分使って支払う」と思いました。

Ruby on Rails開発経験0の自分が2週間で最低限の基礎知識を理解するためにやったこと

$
0
0

急遽PLとして、Railsアプリの開発案件に参画することになり、差し迫ってRails開発のノウハウが必要になった訳だが、直接自分でRailsアプリを開発する訳ではないし、正直どこまで理解すべきか悩ましい。

とはいえ知識0では何かと苦労しそうなので、本投稿は参考書を一読して簡易的なWebアプリを作ったり、自分が過去経験した言語(Java/PHP/C#)での開発と比べてどう違うのか、確認した時のメモ書きです。

全体網羅された参考書の一読

今回はAmazonレビューでも評価上々のこちらで学習を進めみた(今回は★部分を重点的に学習)

現場で使える Ruby on Rails 5速習実践ガイド

本書ではRubyの言語仕様からRails開発手順など、実際に求められる知識が網羅的に説明されている。

■ Chapter 1 - RailsのためのRuby入門 ★
■ Chapter 2 - Railsアプリケーションをのぞいてみよう ★
■ Chapter 3 - タスク管理アプリケーションを作ろう ★
■ Chapter 4 - 現実の複雑さに対応する ★
■ Chapter 5 - テストをはじめよう
■ Chapter 6 - Railsの全体像を理解する ★
■ Chapter 7 - 機能を追加してみよう
■ Chapter 8 RailsとJavaScript
■ Chapter 9 複数人でRailsアプリケーションを開発する
■ Chapter 10 Railsアプリケーションと長く付きあうために

Chapter1 〜 Chapter2でRuby言語仕様やRails開発環境構築を解説。

ちなみに本書ではローカルPC上での環境構築手順が説明されているが、昨今のシステム開発ではDockerを利用するのが当たり前になっているので こちらの記事で Rails + Docker環境を構築して学習。

本書で解説されている Ruby + Rails + PostgreDB の環境構築手順も こちらで紹介。

また多少内容は被るが、Udemyの こちらの動画コンテンツでもざっと学習。

(ハンズオン) タスク管理アプリケーション開発

Chapter3 〜 Chapter4で解説されている タスク管理アプリケーションのハンズオン。

gemを活用しながら機能を実装するので、ハンズオン実施でRails開発の全体像はざっくり把握できると思う。

■ Railsの仕組み( ルーティング / CRUD操作 / テンプレート化 )
■ gem導入と使い方( slim / html2slim / bootstrap / bcrypt )
■ Rails標準であるジェネレータの使い方( コントローラ / モデル作成 )
■ モデルクラスでのバリデーション( 標準機能 / 独自実装 )
■ モデルクラスでのデータ操作( 関連 / 絞り込み / ソート )
■ DBマイグレーション( 主なコマンド / バージョン管理 / テーブル定義の制約制御 )
■ ログイン機能実装( Railsでのセッション管理 / Cookie )

記事を執筆しながらの実装で1日くらい要したが、開発だけであれば2〜3時間で完了すると思う。

Ruby on RailsでCRUD操作が出来るタスク管理アプリケーション構築 Part1
Ruby on RailsでCRUD操作が出来るタスク管理アプリケーション構築 Part2
Ruby on RailsでCRUD操作が出来るタスク管理アプリケーション構築 Part3
Ruby on RailsでCRUD操作が出来るタスク管理アプリケーション構築 Part4
Ruby on RailsでCRUD操作が出来るタスク管理アプリケーション構築 Part5

CakePHPやLaravelを触り慣れている人はスムーズに入っていける印象。

RSpecでの自動テスト

Chapter5ではRSpec導入からテスト実装までを解説されている。

個人的に今回は手を動かせていないが、モダンな開発環境であれば必須領域。

Rails界隈で有名な伊藤淳一さんが綺麗に整理されているので、こちらを一読して実践すれば大丈夫そう。

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」
使えるRSpec入門・その3「ゼロからわかるモック(mock)を使ったテストの書き方」
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」

RailsとJavaScript

Chapter8ではAjaxでRailsサーバとの通信について説明されている。

小規模システムであればRailsモノリスで問題ないだろうけど、最近はAPIファーストでフロントエンドとバックエンドを切り離した構成が多くなっているので、参考レベルに読めば良い内容かな。

Reactチュートリアル
基礎から学ぶVue.js - チュートリアル
Nuxt.js公式ホームページ
Next.js公式ホームページ

Rails採用企業

クックパッド開発者ブログ
Gunosy開発者ブログ
クラウドワークス開発者ブログ
Hulu開発者ブログ
freee開発者ブログ
Wantedly開発者ブログ

その他参考記事

Railsは終わったと言われる理由
マイクロサービス時代に捧ぐ、Railsでの中規模APIサーバ開発のための技術構成
100万行オーバーのモノリシックRailsアプリをマイクロサービス化したクックパッドの手順

【R】 知らず知らず使っている関数『c()』再入門

$
0
0

趣旨

普段ベクトルを作成したりするときに使うc()

c("a","b","c")[1]"a""b""c"

しかし「ベクトル作る関数だな」程度の認識だった私、apply()mapply()で躓きました。
というわけで 『Rユーザーが最も使う関数c()を改めて見てみましょう。』という企画。

c()とは?

まずは名前から行きましょう。公式ヘルプを呼び出します。

help(c)

こちらでも同じものが読めます。
R: Combine Values into a Vector or List

タイトルは 『Combine Values into a Vector or List』です。つまりc()の「c」はCombineに由来するものなんですね。

さらに説明を読むと以下の記述があります。

This is a generic function which combines its arguments.

The default method combines its arguments to form a vector. All arguments are coerced to a common type which is the type of the returned value, and all attributes except names are removed.

まあ要するに、『引数に渡したオブジェクトをベクトルかリストの形式で結合してくれる関数』ということですね。
ここで注目しておきたいのは 引き渡すオブジェクトの種類(データ型・構造)に制約を設けていない点です。つまり、あらゆるオブジェクトを最大公約数的なカタチで結合してくれるようですね。

# install.packages("Hmisc")char<-"moji"df<-data.frame(d=888,999)# c() による結合cmb1<-c(char,df)# 結合データの構造を確認Hmisc::list.tree(cmb1)
データ構造
 cmb1 = list 2 (528 bytes)
.  [[1]] = character 1= moji 
.  d = double 2= 888 999

このように異なるデータ型(characterを格納したvector + numericを格納したdata.frame)であっても問題なくリスト型データに結合してくれます。

そう、意外と『万能』なんです。

二種類の返り値

c()の返り値は、vector型またはlist型の2種類があります。それによって挙動が微妙に違うようです。

リストによる返り値

こっちのほうが簡単なので先に見ていきましょう。

env<-new.env()char<-"moji"num<-1int<-as.integer(0)vec<-c("p","q")fct<-factor(c("Z","Y","X"),levels=c("X","Y","Z"))mtr<-matrix(3330:3335,2,3)lst<-list(l1=111,l2="LIST")df<-data.frame(d=c(888,999))fun<-function(x,y)x+y# c() による結合cmb2<-c(env,char,num,int,vec,fct,mtr,lst,df,fun)# 結合データの構造を確認Hmisc::list.tree(cmb2,maxcomp=length(cmb2))
データ構造
 cmb2 = list 19 (3584 bytes)
.  [[1]] = environment 0
.  [[2]] = character 1= moji 
.  [[3]] = double 1= 1
.  [[4]] = integer 1= 0
.  [[5]] = character 1= p 
.  [[6]] = character 1= q 
.  [[7]] = integer 1= 3
.  [[8]] = integer 1= 2
.  [[9]] = integer 1= 1
.  [[10]] = integer 1= 1
.  [[11]] = integer 1= 2
.  [[12]] = integer 1= 3
.  [[13]] = integer 1= 4
.  [[14]] = integer 1= 5
.  [[15]] = integer 1= 6
.  l1 = double 1= 111
.  l2 = character 1= LIST 
.  d = double 2= 888 999
.  [[19]] = function 1
. A  srcref = integer 8( srcref )= 1 8 1 27 8 27 1 ...
. A A  srcfile = environment 2( srcfilecopy srcfile )

「単一のベクトルで表現されないデータ構造」を格納したオブジェクトを1つ以上含めて結合しようとするとlist型データが返却されます。その際、characternumericといった、結合するオブジェクトのデータ型(データ「構造」ではない。)は返却後も保持されています。
上の例では、list型data.frame型environment型funcion型が「単一のベクトルで表現されないデータ構造」に該当します。

ベクトルによる返り値

「単一のベクトルで表現できるデータ構造」のみを結合するとvector型データが返却されます。
上の例では、list型data.frame型environment型funcion型が「単一のベクトルで表現されないデータ構造」に該当します。

属性について

注意したいのが、c()による結合は、$names属性以外のデータを保持しないということです。
よく分からないかもしれませんが、要はオブジェクトのメインコンテンツ以外は切り捨てられるということです。これは冒頭で引用したヘルプにも書いてあることです。

(中略) all attributes except names are removed.

これがどのように影響するのか、具体的には例えば以下のようなことが挙げられます。

結合するデータ型症状回避策
data.frame型data.frame属性が失われるため、list型に変換されてから結合されてしまう。list()による結合
matrix型dim属性が失われるため、一行のベクトルに変換されてしまう。一旦data.frame型へ変換させる。

その上でさらにlist型を回避したい場合は上記を参考。
factor型levelsordered等の属性情報が失われるため、そのまま結合させるとinteger型のベクトルに変換されてしまう。ラベルを保持したい場合は、as.vector()等で変換してから結合を行う。

属性全体を保持したい場合は、list()による結合が有効。

list()による結合

以上に関連して、c()を使った結合とlist()による結合には多少の差があります。

c() による結合
>c(df)$d[1]888999
list() による結合
>list(df)[[1]]d18882999
データ構造の比較
# c() による結合# data.frameがlist型に強制変換されている>c(df)[[1]][1]888999>is.data.frame(c(df)[[1]])[1]FALSE# list()&nbsp;による結合# data.frameが保持されている>list(df)[[1]]d18882999>is.data.frame(list(df)[[1]])[1]TRUE

このように、c()の場合はデータ構造は一律でvector型またはlist型に変換されますが、list()の場合は元のデータ構造が保持されることになります。
また、matrix型の場合も示していきます。

c() による結合
>c(mtr)[1]333033313332333333343335
list() による結合
>list(mtr)[[1]][,1][,2][,3][1,]333033323334[2,]333133333335

factor型データの結合

もう一つ、factor型を結合したときの挙動を記しておきます。

>c(fct)[1]321

このように順序データとして結合されます。これが望ましいケースもあるので、回避策をするか否かはケースバイケースでご判断ください。

回避策1
# ラベルのほうが残るが、Levels等の属性情報は失われるため、# 結合後は単なる文字列ベクトルとして扱いたい場合に有効。>c(as.vector(fct))[1]"Z""Y""X"
回避策2
# すべての属性情報を保持できるため、# 結合後もfactorとして扱いたい場合には有効。>list(fct)[[1]][1]ZYXLevels:XYZ

names属性について

ここまでは属性情報は切り捨てられるというお話で進めてきましたが、例外的にnames属性については維持されるようです。

>vec2<-vec>names(vec2)<-c("P","Q")>c(vec,vec2)PQ"p""q""p""q"

ベクトル結合の注意点

ベクトルを結合する際に、返り値がリストの場合、ベクトルの各要素がリストの各要素に変換されてしまいます。

>c(vec,df)[[1]][1]"p"[[2]][1]"q"$d[1]888999

これを回避したい場合は、list()による結合か、一度ベクトルをlist型データに格納することをおすすめします。

list() による変換
>list(vec,df)[[1]][1]"p""q"[[2]]d18882999
list() を噛ませた c() による変換
>c(list(vec),df)[[1]][1]"p""q"$d[1]888999# data.frameも保持したい場合は以下のようにする>c(list(vec),list(df))[[1]][1]"p""q"[[2]]d18882999

オプションについて

c()にはいくつかのオプションが引数で設定できます。

引数説明規定値
recursivevector型に強制変換するかFALSE
use.namesnames属性を保持するかTRUE

recursive

data.frame型との結合のように返り値が通常list型になる場合に、強制的にvector型に変換するかどうかを設定できます。

recursive = F (規定値)
# c(df,char)>c(df,char)$d[1]888999[[2]][1]"moji"
recursive = T
>c(df,char,recursive=T)d1d2"888""999""moji"

use.names

名前の通り、names属性を保持するか否かを選択できます。

names = T (規定値)
>c(vec,vec2)PQ"p""q""p""q"
names = F
>c(vec,vec2,use.names=F)[1]"p""q""p""q"

おわりに

基本的な関数ながら意外と万能で奥深い?c()でした。

とはいえ普段はそんなに気にせず使ってもいいと思いますが、たまにトラブルが起きるかもしれませんので、その時はまた見返してもらえたら嬉しいですね。

Enjoy!

おしまい。

参考

Google AutoML Translationの使い方

$
0
0

はじめに

GCPのGoogle AutoMLTranslationを使う機会があったので記録としてメモしていこうと思います!
学習にかかるお値段すごいのでなかなか手が出せなかったのですが、機会に恵まれて良かったです:sunny:

GCP

GCPとはGoogle Cloud Platformの略でGoogleさんが運営しているクラウドサービスになります。
できることはいろいろあるのですが、今回はその中のGoogle AutoMLTranslationを使用します!

AutoML

AutoMLとは機械学習の知識がなくてもモデルの構築を可能にするシステムのことです。
データの前処理から、訓練用、テスト用にデータを分けて、モデルを作って、パラメータを調整して、、、などの処理がすでにでいるようになっていて、データさえそろっていればモデルのトレーニングがすぐにできてしまう優れもの!
しかも今回使用するGoogleのAutoMLはモデルができたら作成したモデルをすぐにAPIにできるし、GoogleCloud上に直接デプロイが可能なのだそうです!

使い方

AutoMLTranslationの使い方を紹介していきます!
詳しく載っているのはもちろんドキュメントなので詳しくはこちらを参照して下さい。
Google AutoMLTranslationのドキュメント

学習を始める前に

こちらのドキュメントを参考にしてAutoMLが使えるようにして下さい。
始める前に
(サービスアカウントはAPIとして使用するときに必要だっただけな気がするので多分APIを使用しないならいらない)

データセット作成

左端のナビゲーションメニューを開いて「翻訳」を見つけ出して、翻訳のダッシュボードを開きます。
スクリーンショット 2020-03-03 17.12.37.png

今回は左のAutoMLTranslationを使用します。
スクリーンショット 2020-03-03 17.17.43.png
開始をクリックするとデータセット画面に移行します。

スクリーンショット 2020-03-03 18.14.47.png
「データセットを作成」をクリックするとデータセット作成画面が現れます。

スクリーンショット 2020-03-03 17.24.41.png

やることは、
・データセット名を決める
・ソース言語(翻訳したい言語)を決める
・ターゲット言語(翻訳結果として出して欲しい言語)を決める
例)日本語から英語に翻訳して欲しいとき
  ソース言語→日本語
  ターゲット言語→英語

全部決めたら「作成」ボタンを押す。

これでデータセットが作成されました!

しかしこのデータセットの中にはまだ何もデータが入っていません。
ここからデータを入れていこうと思います。

データ作成

データはソース言語とターゲット言語の文章の対訳になります。
例) 日本語を英語に訳すモデルを作りたいとき

日本語英語
こんにちはHello
初めましてNice to meet you
ねこが可愛いCat is cute

このような対訳を自分のカスタマイズしたい分野に合わせて作っていきます。
ソース言語は左、ターゲット言語は右にして対訳を作成します。
データの形式は.tsvにして下さい。
データセットを何処かから引っ張ってきてもこの形に準じていれば大丈夫です!
わたしはデータがなかったので作ることになりましたが、、、

また、データのファイルはtrain,val,testの3つに予め分けておくことをお勧めします。

注意
test,valにそれぞれ100以上の例文が入っていないと学習ができません

データを用意できたら、先ほど作成したデータセットにインポートしていきます。
作成したデータセットを選択し、インポートタブを開きます。

Cloud Strageにデータのファイルを入れておくと便利なのでそちらをお勧めしますが、パソコンからもファイルのアップロードが可能です。
その際もCloud Strageに保存することになるのでバケットは作っておくといいと思います。
また、バケットを作成するときはリージョンをus-centralにして下さい。

スクリーンショット 2020-03-03 17.56.41.png

そしておすすめはトレーニング、検証、テストに別のファイルを使用します(上級者向け)にチェックを入れて、それぞれファイルをインポートすることです。
よくわからない仕様ですが、それをしない場合testの内容が書き換えられてしまうことがあります。

またすごく困ったのは、test,valにそれぞれ100以上の例文が入っていないと学習ができないことです。
これでいつものtrain:80%, val:10%, test:10% を守るとなると、全部で1000文必要になります、、
ただ勉強でやるには自分で作るとなると過酷ですね、、

ファイルを指定できたら、「続行」ボタンをクリック。
インポートに少し時間がかかります。

学習

インポートができたらトレーニングタブに移動します。

スクリーンショット 2020-03-03 18.45.21.png

インポートしたファイル名と正常にインポートされた例文数が表示されます。
トレーニングを開始ボタンを押すと、「新しいモデルのトレーニング」という画面が出てきます。
スクリーンショット 2020-03-03 18.48.38.png

やることは、
1.モデル名を決定する
2.ベースモデルの決定
です。
2.について、最初はGoogle NMTモデルのみが選択できます。
一つでも、あるソース言語とターゲット言語の組み合わせでモデルを作成すれば、その作成したモデルをベースに追学習させることができるようになります。
精度をどうしてもあげたいときは作成したモデルにどんどん追学習していく方がお勧めです。(過学習かも。。?)
わたしの場合、一回の学習ではほとんどNMTと変わらない結果でした。
わたしのデータに同音異義語が多かったせいかもしれませんが、、

1、2、ができたら「トレーニングを開始」ボタンを押すと学習が始まります。
ここからが長い、、もし1000文入れていたら2時間はかかります。
そして大体2時間で1万円程度のお金が吹っ飛びます!!お気をつけ下さい。

予測

学習が終わったら、予測のタブに移動して例文を入力してみると、新しくできたモデルとGoogleNMTモデルの出力結果を比較することができます。

また、モデルIDや、APIの使いかたなども表示されています!
ぜひ使ってみて下さい!

終わりに

今回、初めてAutoMLという技術に触れさせていただき、とても勉強になりました。
実際に使ってみた感想としては、評価関数にBLEUを使っていたり、そもそもデータを集める時点で機械学習の知識が一切いらないとは思えないな、というのが正直なところです!
でも、自分でモデルを作成しないでいいというのは確かに楽だし、すぐにAPIとして利用できるのも便利だなと思いました!
データ突っ込むだけって楽ですねぇ〜!
でも工夫できるとこがデータしかないので精度あげなきゃってなると大変でした、、
勉強として触れるのはなかなか大変なことだとは思いますが、興味があったら是非やってみて下さい:hugging:

参考文献

Google AutoML Translationドキュメント

Viewing all 21163 articles
Browse latest View live