Briswell Tech Blog

ブリスウェルのテックブログです

AKAZEによる文字検出

毎月のブログ更新の期限が近づいてきました!
今年トップレベルの低気圧で頭がクラクラしております。

画像処理技術を一つご紹介いたします。

OpenCVのAKAZE(Accelerated-KAZE)という特徴量検出の手法を試してみました。KAZEは「風」から命名されています。この手法を用いることで「2つの画像に同じものがあるか」の判別ができるようになります。

tech.briswell.com

  1. 前回の記事のWord Cloud画像
  2. 簿記の文字画像

を使用して、それぞれの特徴量をAKAZEにより計算し、その計算した特徴量をマッチングさせてみます。

f:id:KenjiU:20211130211922j:plain

「簿記」取得できました!

実際はまだ3級合格できておりません。次回は4度目のチャレンジです。

AWS Network Firewall の初期設定

こんにちは、としです。
最近はプライベートでウイスキーの勉強を始めました。
元々焼酎ばかり呑んでいたので、新鮮でとても楽しく、美味しいウイスキーにいっぱい出会えて幸せな気分です。

本日は [AWS Network Firewall の初期設定] について書いてみようと思います。

0.初めに

セキュリティ要件で今後必要になってきそうだな、と感じたので、AWS Network Firewall を触ってみました。
AWS Network Firewall とは、などは色々な記事で書かれているので、割愛します。
まだまだルール設定やALBとの同居など、自分の中で問題はありますが、下記構成での導入はできたので、備忘録含め、記載していこうと思います。
※時々、Firewallを間違えてFilewallと記載している部分があります。間違えました🥺

f:id:Toshi_bw:20211109131055p:plain

1.VPCの作成

VPCを新しく作成します。

f:id:Toshi_bw:20211109131114p:plain

作成後です。
f:id:Toshi_bw:20211109134030p:plain

2.サブネットの作成

作成したVPCに対して、サブネットを作成します。
f:id:Toshi_bw:20211109134116p:plain f:id:Toshi_bw:20211109131414p:plain
作成後です。
f:id:Toshi_bw:20211109134200p:plain

3.インターネットゲートウェイの作成

インターネットゲートウェイを作成します。
f:id:Toshi_bw:20211109131504p:plain


作成したVPCにアタッチします。

4.ルートテーブルの編集

作成したサブネットのルートテーブルに対して、作成したインターネットゲートウェイをアタッチします。
f:id:Toshi_bw:20211109131648p:plain

5.EC2インスタンスの作成

適当なEC2インスタンスを作成し、Apacheをインストールし、http通信を可能とし、アクセスができることを確認します。
※EC2の作成方法などは割愛します。

6.Firewall サブネットの作成

先ほど作成したVPCに対して、Firewallサブネットを作成します。
f:id:Toshi_bw:20211109134245p:plain f:id:Toshi_bw:20211109131912p:plain


7.Firewall の作成

VPC画面のLeft menuの下の方にファイアウォールがあるので、そこから新規作成を行います。 
※少し待ち時間があります。
f:id:Toshi_bw:20211109132002p:plainf:id:Toshi_bw:20211109132009p:plainf:id:Toshi_bw:20211109132017p:plain


8.ステートレスルールグループの設定

お試しなので、とりあえず80ポートのみを許可設定しています。
f:id:Toshi_bw:20211109132441p:plainf:id:Toshi_bw:20211109132449p:plainf:id:Toshi_bw:20211109132456p:plainf:id:Toshi_bw:20211109132504p:plain
送信先、カスタムIPはEC2の [プライベート IPv4 アドレス] を入力してください。

f:id:Toshi_bw:20211109134359p:plain

9.ステートレスデフォルトアクション

上記指定ルール以外を拒否します。
f:id:Toshi_bw:20211109132607p:plain

10.ルートテーブルの設定

ルートテーブルは全部で3つ存在します。
※個人的にここが1番躓きました。

Firewall Internet Gataway(新規作成)
f:id:Toshi_bw:20211109132726p:plainf:id:Toshi_bw:20211109132733p:plain


Firewall Public
※EC2で使用しているサブネットのルートテーブル
f:id:Toshi_bw:20211109132744p:plain

Firewall Table
Firewallで使用しているサブネットのルートテーブル
f:id:Toshi_bw:20211109132800p:plain

11.最後に

ここまでの作業で一旦構成図の導入は完了となります。
作成したEC2インスタンスに80ポートでのアクセスは可能で、SSHの接続は拒否されることが確認できると思います。


様々なルールが設定可能なので、ここをいじくり回して今後のシステム開発に役立てていこうと思います。
f:id:Toshi_bw:20211109132917p:plain


最後まで読んでいただき、ありがとうございます。
これからも色々なサービスが出てくる、進化していくので、いっぱい触っていこうと思います。

Word Cloud で記事を可視化

最近のブログ記事の内容を可視化すべく

WordCloud for Python documentation — wordcloud 1.8.1 documentation

こちらの「Word Cloud」ライブラリを利用してみます。その名の通り、頻繁に出てくる「単語(Word)」を、その出現頻度に比例する大きさで「雲(Cloud)」のように並べて表示してくれます。以下のようなパラメータ設定が可能です。

wordcloud = WordCloud(
    font_path = "/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc", #フォントのパス
    width = 900, height = 600, #キャンバスのサイズ
    background_color = "white",   #背景色
    stopwords = ['さん','くん'], #除外する単語
    max_words = 500,   #単語数の上限
    min_font_size = 4,   #最小のフォントサイズ
    collocations = False   #複合語のオプション
    ).generate(words_blog)

Welcome to janome's documentation! (Japanese) — Janome v0.4 documentation (ja)

また、こちらの「Janome」ライブラリを使用して、単語を名詞のみに絞ります。ただし、代名詞(例:そこ)、非自立(例:もの)、数(例:1)は除外します。

word_list=[]
for token in tokens:
    word = token.surface
    part_1 = token.part_of_speech.split(',')[0]
    part_2 = token.part_of_speech.split(',')[1]
     
    if part_1 == "名詞":
        if (part_2 != "代名詞") and (part_2 != "非自立") and (part_2 != "数"):
            word_list.append(word)

では、確認してみましょう。

f:id:KenjiU:20211031224401p:plain

古き良きものを今の時代にも、伝えていきたい所存でございます。

暑さ寒さも彼岸まで

朝晩ヒンヤリとして過ごしやすくなってきましたね。秋到来ですが、弊社には、7月と9月に新しい社員が入社し、春のようなフレッシュさをもたらしています。みんなでガンガン挑戦していきましょう!

という出だしでしたが...
今回は少しネタが切れてしまいまして

最初は人として検出されてしまったが、途中自転車やバイクになりすまそうとし、最終的に気配を消す、お侍くんをご紹介いたします。(少し演出を施しております。お含みおきください。)

f:id:KenjiU:20210926193347g:plain
お侍くん検出

江戸商売と簿記

最近、社内で簿記検定が流行っています。僕は未だに簿記3級の合格ができず、もがいております...

簿記の勉強を始めて感じたのは、ITエンジニアとして会計まわりのシステムの構築に役立つだけでなく、色々な取引や決算手続きを学べるので、経営の流れ・仕組みの理解も深まり、とても面白いです。

ただ、夜な夜な参考書や問題集ばかりを見ていると眠くなってくるので、Pythonと絡めて簿記の勉強が出来ないかと思っていたところ、

Pythonで学ぶ簿記 ~簿記一巡の流れ編~ - Qiita

こちらの記事にて、簿記一巡の流れをPythonで実装されておりました。とても分かりやすいですね。

参考にさせていただき、江戸の呉服商の取引の仕訳を作成していきたいと思います。ちなみに江戸時代の帳簿は、現在の「複式簿記」ではなく「単式簿記」(家計簿のように現金の出入りを記録)の形で作成されていたようです。

1. 呉服屋を設立

明和八年(1771年)の元日に、現金100両を資本金として、呉服屋を設立します。

f:id:KenjiU:20210829225225p:plain

現金(資産)の増加 → 借方
資本金(純資産)の増加 → 貸方

最近、明和八年の江戸地図を購入したので、ずっと眺めています。翌年の明和九年(迷惑年とも言われた)には、江戸三大火の一つの明和の大火が発生しました。

2. 反物を仕入

商品80両分を仕入れ、代金は掛け払いとします。

f:id:KenjiU:20210829225236p:plain

商品(資産)の増加 → 借方
買掛金(負債)の増加 → 貸方

江戸時代は、反物のまま売買するのがルールで、着物への仕立ては自分の家でやるか別途仕立屋にお願いしていました。

3. 反物を販売

仕入れた商品を50両で販売し(原価は40両)、代金は掛け売りとします。

f:id:KenjiU:20210829225306p:plain

売掛金(資産)の増加 → 借方
売上(収益)の増加 → 貸方

f:id:KenjiU:20210829225322p:plain

売上原価(費用)の増加 → 借方
商品(資産)の減少 → 貸方

江戸時代の掛け売りの集金は、お盆・大晦日の年2回が一般的でした。

4. 仕入代金を支払

仕入代金80両のうち60両を支払います。

f:id:KenjiU:20210829225427p:plain

買掛金(負債)の減少 → 借方
現金(資産)の減少 → 貸方

5. 販売代金を集金

販売代金50両のうち40両を集金します。

f:id:KenjiU:20210829225437p:plain

現金(資産)の増加 → 借方
売掛金(資産)の減少 → 貸方

6. 損益振替と資本振替

売上(50両) - 売上原価(40両) = 当期利益(10両)

f:id:KenjiU:20210829225505p:plain

7. 貸借対照表の作成

f:id:KenjiU:20210829234338p:plain

f:id:KenjiU:20210829231841p:plain

8. 損益計算書の作成

f:id:KenjiU:20210829225532p:plain

f:id:KenjiU:20210829231306p:plain

簿記の流れがつかめそうです!かたじけない。

武士の移動経路検索

幕末の万延元年(1860)に紀州和歌山藩の武士である酒井伴四郎は江戸に単身赴任しました。

その時の日々の生活を綴った日記が東京都江戸東京博物館に保管されており、江戸の生活、文化を知る重要な文献となっています。まさか自分の日記が、後の世の人の目に触れて研究対象にもなるとは、想像すらしなかったでしょう。

伴四郎さんは、赤坂の紀州藩江戸屋敷の長屋に住んでいました。休日を利用して、江戸市中を散策していたようで、東京湾や市中を見渡せる観光スポット「愛宕山」にも行っていたようです。

江戸時代の移動手段は、自分の足(または駕籠や馬)です。赤坂から愛宕山(港区愛宕1丁目)までどのような経路でどのくらいの時間で移動していたのでしょうか?

現代の地図になってしまいますが、Googleマップで経路検索してみます。単にGoogleマップで検索するのでは粋じゃないので、Google Maps Platformの「Directions API」をPythonから呼び出してみます。

【Python】「Google Map API」を利用して2点間のルート情報をJson形式で取得する方法。

こちらのサイトを参考にさせていただきました。

赤坂の紀州藩江戸屋敷近くの「紀伊国坂」から「愛宕」までの「徒歩」での移動経路について、以下のように、「Directions API」のパラメーターを指定をすることで検索することができます。

import urllib.request, json
import urllib.parse
import datetime

#Directions API endpoint
endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
#Directions API Key
api_key = '[Google Maps PlatformのAPIキー]'

#出発地
origin = '紀伊国坂'
#目的地
destination = '愛宕'
#移動手段
mode = "walking"

#リクエストパラメータをセット
request = 'language=ja&origin={}&destination={}&mode={}&key={}'.format(origin,destination,mode,api_key)
#URLエンコード(safeには変換させない文字を指定)
request = urllib.parse.quote_plus(request, safe='=&')
#リクエストURLを生成
request = endpoint + request

#Directions APIを実行
response = urllib.request.urlopen(request).read()
#実行結果を取得
directions = json.loads(response)

for key in directions['routes']:
    for key2 in key['legs']:
        print('距離:' + key2['distance']['text'])
        print('所要時間:' + key2['duration']['text'])

実行結果は

距離:2.9 km
所要時間:37分

となり、直接Googleマップで経路検索した結果と同様でした。

落ち着いたら、実際に歩いてみようと思います。

粋なキャッチコピーを生成

土用の丑の日

江戸時代の天才「平賀源内」が生み出したキャッチコピーと言われています。夏に鰻を食べる習慣がなかった江戸時代の人の心を、がしっとつかみました。

僕のような凡人でも何か上手いキャッチコピーを(AIの力で)作れないだろうか...

調べてみると、マルコフ連鎖という手法を用いると、教師データから自動的にキャッチなコピーを生成することができるようです。

試してみましょう!

マルコフ連鎖を使ってブログの記事を自動生成してみた - karaage. [からあげ]

こちらのからあげさんのサイトを参考にさせていただきました。

1. 日本語の形態素解析エンジンをインストール

brew install mecab
brew install mecab-ipadic

2. Python3で使用するためのライブラリをインストール

brew install swig
pip install mecab-python3

3. 文章自動生成プログラムのセットアップ

GitHub - karaage0703/TextGenerator: マルコフ連鎖を使った文章自動生成プログラム+はてなブログ投稿スクリプト

こちらを利用させていただきました。

Python3で実行するため
・xrange
・encode / decode
・print
の記法を変更いたしました。

4. DBファイルの生成

python PrepareChain.py sample.txt

引数の「sample.txt」には教師データを指定します。

5. キャッチコピーを生成

python GenerateText.py 2

引数には生成する文章数を指定します。

6. 結果

tech.briswell.com

今までの江戸AI記事を教師データにして生成してみました。

3つほどご紹介します。

生成結果①

現代のロボットは、何かワクワクしませんが、江戸ブログでは次第に季節とずれてきました。
こちらのサイトで「くずし字」の美学と言われています。

生成結果②

何もひねりはあります。
夜な夜な江戸の会話術、参考になれば素敵ですね。

生成結果③

お主も悪よのう。
2月に「くずし字」をCNNに学習させて、それが発明のヒントになるのでしょうか。

面白いですね。思いがけないキャッチコピーが生まれるかも!?

VPCピアリングの設定

今回は
アカウントAのRDS
アカウントBのEC2(実際はElasticBeanstalk)
を接続したい、という要件でした。

・ピアリング接続の設定
アカウントB
VPC画面を起動
メニューの「ピアリング接続」を選択
「ピアリング接続の作成」をクリック
ピアリング接続ネームタグ = お好きなネームタグ
VPC (リクエスタ) = 接続したいEC2が属するVPC
アカウント = 別のアカウント
アカウント ID = アカウントA のアカウントID
リージョン = 今回はRDSも同様リージョンなので、このリージョン
VPC ID (アクセプタ) = アカウントA の RDS が属するVPC
を入力し「ピアリング接続の作成」を行いました。

すると、アカウントAに対して承認待ち、というステータスになるので、一度アカウントAに切り替えます。

アカウントA
同様に、VPC画面を起動し、「ピアリング接続」を選択します。
すると、1行承認待ち、というレコードが存在しているはずなので、承認を行います。
※アカウントBで申請後、5分程度待たないとレコードが表示されませんでした。

これでピアリング接続の作成は完了です。

f:id:Toshi_bw:20210629143344p:plain
VPCピアリング接続


ただ、これだけだとEC2 → RDSへは接続はまだできません。
続いて、それぞれのVPCが属するルートテーブルの修正が必要です。

仮に、
リクエスタCIDR(アカウントB) = 10.150.0.0/16
アクセプタCIDR(アカウントA) = 10.153.0.0/16
だとします。

アカウントBの VPC画面を起動し、右側にある「メインルートテーブル」
からルートテーブルの画面へ遷移します。
ルート → ルートの編集
に入り、「ルートを追加」をします。
送信先 = 10.153.0.0/16
ターゲット = ピアリング接続 を選択後、該当ピアリングIDを選択し、保存を行います。

続いて、アカウントA のVPC画面を起動し、同様にルートを追加を行います。
送信先 = 10.150.0.0/16
その他は同様で保存を行います。

これでルートテーブルの設定は完了です。
私はネットワークACLは元々全て開放されていたので、特に修正は必要ありませんでした。

ここで、一度接続を試しました。
EC2 → RDS への接続は弾かれました。
※RDSはパブリック接続を許可しています。

何が原因で接続できていないのか不明なため、一度
EC2からEC2へのSSH接続を検証しました。

結果、パブリックアドレスでは接続できませんでしたが、プライベートアドレスでの接続は行えました。
となると、恐らくDNS周りの問題か?
ということになりまして、再度VPC画面の確認を行ったところ、
VPC
DNS ホスト名 = 無効
DNS 解決 = 有効
両方のアカウントが上記設定になっていたので、
DNS ホスト名 = 有効
に変更を行い、再度試しましたがまだNG。

続いてVPC ピアリング画面へ戻り、設定を確認したところ、
アクセプタ VPC からプライベート IP への DNS 解決 = 無効
になっていたので
アクセプタ VPC からプライベート IP への DNS 解決 = 有効
に修正を行いました。

この設定を行ったところ、無事やりたかったEC2 → RDS への接続を行うことができました。

nslookup `RDS HOST NAME` 


で確認できますが、最後のIP部分がプライベートIPへ解決できているか、で見れるようでした。

中々手こずりましたが、やりたかったことにたどり着けたので、備忘録として残しておきます。

くずし字OCRアプリ

「安い、早い、うまい」

が好まれるせっかちな江戸っ子のように、今回もサクッとご紹介いたします。

codh.rois.ac.jp

こちらのサイトで「くずし字」がデータセットで提供されております。

さて、今回は、この「くずし字」をCNNに学習させて、現代の日本語文字に変換するアプリケーションを構築してみます。

古文書がAIによりスラスラ読めるようになれば素敵ですね。

GitHub - rois-codh/kmnist: Repository for Kuzushiji-MNIST, Kuzushiji-49, and Kuzushiji-Kanji

こちらで公開されているbenchmarksのコード

kuzushiji_mnist_cnn.py

の最後に以下の2行を加えて、学習したモデルと重みファイルを保存します。

open('k_mnist_cnn_model.json','w').write(model.to_json())
model.save_weights('k_mnist_cnn_weights.h5')

その学習結果を、PythonのWebフレームワーク「Flask」を使ったアプリケーションから呼び出します。(コードは後日公開予定です)

f:id:KenjiU:20210531183544p:plain
くずし字OCRアプリケーション

上図のように「くずし字」の画像をアップして実行すると、現代の文字に変換されます!
今回は「くずし字」でしたが、データセットがあれば同じようなことが実現できます。

余談ですが...
江戸時代に「豆腐百珍」という、100種の豆腐料理を解説したベストセラー料理書がありました。

codh.rois.ac.jp

「くずし字」で記載された本のデジタル画像も提供されています。

その「豆腐百珍」の58番目に、奇品として掲載されている「玲瓏(こおり)豆腐」というのが気になったので実際に作ってみました。

f:id:KenjiU:20210531131633j:plain
玲瓏(こおり)豆腐

まさに氷のようにも見え、夏にふさわしい一品でした。

江戸時代のロボット

からくり人形は江戸時代の庶民を熱狂させたものの一つです。

からくり人形師 九代 玉屋庄兵衛展―伝統の技と挑戦―(予告動画)|高島屋 - YouTube

こちらは「からくり人形師 九代 玉屋庄兵衛展」の動画ですが、まさに人間の動きそのもの。電気を全く使用せず、木でできた歯車と、ぜんまい(江戸時代はくじらのひげを利用)仕掛けで実現しており、驚きです。まさに江戸時代のロボットですね。

現代のロボットは、作業効率化・自動化のために用いられることが多いですが、江戸時代のからくり人形は、人を驚かせ感動させるためのものでした。約260年間にわたる天下泰平の世にあった江戸時代ならではの文化です。

また、からくりの技術を技術者から大衆へも共有すべく「機巧図彙(からくりずい)」という本が1796年に刊行されてベストセラーになりました。

ja.wikipedia.org

この「機巧図彙」には以下のような補足文があります。

此書の如き、実に児戯に等しけれとも、見る人の斟酌に依ては、起見生心の一助とも成なんかし

この本に書いてあることは、子供の遊びのようなものだけど、見る人の理解によっては、何か新しい発想を得て、それが発明のヒントになるでしょう。

現代にも通じる素敵な思想です。

さて、今回はロボットということで

Bullet Real-Time Physics Simulation | Home of Bullet and PyBullet: physics simulation for games, visual effects, robotics and reinforcement learning.

こちらのPyBulletというオープンソースの3D物理シミュレーションツールで人型のロボットを動かしてみます。赤い球を走って追いかけるという動作を学習済みです。

f:id:KenjiU:20210430113252g:plain
動作結果

少々のことではへこたれず、やり遂げていこうと思います。