技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

DeepLerning らしいDeepLerning実装

white-azalea.hatenablog.jp

ここに、Dropout 層とか色々積んでみたというもの。
尚、この記事初めて見た人は突然何のことやらだと思うので、この辺の 2021/2 月あたりから継続してるのでその辺見ると良いかも?

white-azalea.hatenablog.jp

やってみてわかったことは、大量のデータセットでいきなり学習させるとかではなくて、そこそこ小さなデータセットで 1 層づつ増やしていった方が無難だと思った。

いきなり層を増やしてエラー起こすと、何層目で設定ミスしたのか本気で分からなくなるので…。
行列計算の問題なので、行列サイズ(input / output) の形状一つでもミスすると、即エラーです。

尚、im2col 変換や col2im は以前の記事参照で。

畳み込み層

画像の特徴抽出層。
内部でフィルタを持っていて、フィルタによって特徴を拾う。

尚、ニューロンからのリクエスト(backpropagation)を受けて、よりリクエストに合ったフィルタに形状変更していく。

class ILayer:
    def forward(self, x, is_test):
        pass
    def backward(self, grad_y):
        pass
    def update(self, eta):
        pass

class ConvLayer(ILayer):
    def __init__(self, x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad, wb_width):

        # パラメータをまとめる
        self.params = (x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad)
        
        # フィルタとバイアスの初期値
        self.w = wb_width * np.random.randn(n_flt, x_ch, flt_h, flt_w)
        self.b = wb_width * np.random.randn(1, n_flt)
        
        # 出力画像のサイズ
        self.y_ch = n_flt  # 出力チャンネル数
        self.y_h = (x_h - flt_h + 2*pad) // stride + 1  # 出力高さ
        self.y_w = (x_w - flt_w + 2*pad) // stride + 1  # 出力幅
 
        # AdaGrad用
        self.h_w = np.zeros((n_flt, x_ch, flt_h, flt_w)) + 1e-8
        self.h_b = np.zeros((1, n_flt)) + 1e-8
        
    def forward(self, x, is_test):
        n_bt = x.shape[0] 
        x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad = self.params
        y_ch, y_h, y_w = self.y_ch, self.y_h, self.y_w
        
        # 入力画像とフィルタを行列に変換
        self.cols = im2col(x, flt_h, flt_w, y_h, y_w, stride, pad)
        self.w_col = self.w.reshape(n_flt, x_ch*flt_h*flt_w)
        
        # 出力の計算: 行列積、バイアスの加算、活性化関数
        u = np.dot(self.w_col, self.cols).T + self.b
        self.u = u.reshape(n_bt, y_h, y_w, y_ch).transpose(0, 3, 1, 2)
        self.y = np.where(self.u <= 0, 0, self.u)
        return self.y
    
    def backward(self, grad_y):
        n_bt = grad_y.shape[0]
        x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad = self.params
        y_ch, y_h, y_w = self.y_ch, self.y_h, self.y_w
        
        # delta
        delta = grad_y * np.where(self.u <= 0, 0, 1)
        delta = delta.transpose(0,2,3,1).reshape(n_bt*y_h*y_w, y_ch)
        
        # フィルタとバイアスの勾配
        grad_w = np.dot(self.cols, delta)
        self.grad_w = grad_w.T.reshape(n_flt, x_ch, flt_h, flt_w)
        self.grad_b = np.sum(delta, axis=0)
        
        # 入力の勾配
        grad_cols = np.dot(delta, self.w_col)
        x_shape = (n_bt, x_ch, x_h, x_w)
        self.grad_x = col2im(grad_cols.T, x_shape, flt_h, flt_w, y_h, y_w, stride, pad)
        return self.grad_x

    def update(self, eta):
        self.h_w += self.grad_w * self.grad_w
        self.w -= eta / np.sqrt(self.h_w) * self.grad_w
        
        self.h_b += self.grad_b * self.grad_b
        self.b -= eta / np.sqrt(self.h_b) * self.grad_b
続きを読む

メモ書き:ディスプレイを破棄するにあたり

在宅で使ってたディスプレイが壊れたので、これどうするかなーと思ってみたら、破棄方法が結構めんどくさかったので忘れる前にメモ。
(因みに、調べてみたらAmazonで買って1年以内だったので、無事修理に出せた)

ディスプレイは普通には捨てれない

燃えないゴミに出したらアカン。液晶ディスプレイは「リサイクル家電法」という法律があり、単純に捨てることができない。
なので、原則としては以下いずれかの手段で手放す必要があります。

  1. 自治体の回収
  2. メーカーの回収
  3. 一般社団法人 3R 推進協会 or 破棄業者に頼む

自治体の回収

自治体によってやってるかどうかが決まる。
例えば自分の自治体は対応してなかった。

パソコンの出し方Q&A | 市川市公式Webサイト

この手のページは大体の自治体にあるので探すと良いと思う。

メーカーの回収

パソコンを製造・販売または輸入・販売する全ての事業者には回収・再資源化の義務があります

これは法律、ルールの問題なので、会社が生きている場合は基本的に対処してもらえる。
しかも、以下のマークがついているものについては、破棄費用はタダになる。

f:id:white-azalea:20210422191407p:plain

つっても送料位はかかるんだろうけど…一般的メーカーの窓口一覧はこっち

www.pc3r.jp

PCモニターの回収 各メーカーのPCリサイクル案内ページ - カラーマネジメント実践ブログ 〜フォトレタッチの現場から〜

一般社団法人 3R 推進協会 or 破棄業者に頼む

メーカーが存在しない、個人輸入品だなどの場合、回収メーカーがない事がある。(自作とかも含む)
破棄業者でもいいとは思うのだけど、一応法人にしとくのが一番安全だと思う。

申し込みURLは 家庭から排出されるパソコンの回収申込み | ご案内

英語勉強したい人に「Subtitles for Language Learning」

Amazon Prime Video。コロナ禍ではこういうのがお供になるはず。
ついでに英語の勉強もしてみようか。

www.subtitlesfll.com

ということで入れてみた図

f:id:white-azalea:20210421221153p:plain

アマプラの画面はキャプチャできない様になっているので、そこはあきらめで(汗

尚、再生しているのはファンタビ(字幕版)で、日本語字幕の下の黒枠に英語字幕、画面右にその字幕とカーソルを合わせたときに単語の意味が出てくる。
加えて、右の字幕をクリックするとその場面まで自動スキップもしてくれる。

これは…捗るねw

Salesforce開発の基礎編2

Aura コンポーネントの基本概念

trailhead.salesforce.com

日本語が長ったらしく意味不明なので、調訳。

  • バンドルと要求のライフサイクルについて
    • 根本的にブラウザ側で動作するコンポーネントである。
    • ハンズオン内容は、ほとんど空っぽの Aura Component を作成してデプロイするだけなので、特にハマることはないはず
  • アーキテクチャ概念について
    • 概念: 複数ページアプリケーションと単一ページアプリケーション:
      VFみたいに画面をページ遷移して処理する…様な扱いではなくて、画面状態を変更するという形で画面を変えていく。単一ページ内で状態を変えながら処理していくモデルを単一ページアプリとここでは定義してる。
    • 概念: ページとコンポーネント:
      Aura Component は一つ一つ独立した小さなコンポーネントを、1ページ内に複数配置して動作させるイメージになる。
      • コンポーネント間はイベントを飛ばしあって通信する。コントローラでは特定のイベントに反応して処理するような作りをしていく。
      • 上記の様にコンポーネント間の繋がりが薄いので、グループ的に組み合わせて作成できる。
      • Aura コンポーネントは色々なところで使える
    • 概念: アプリケーションコンテナ
      Aura コンポーネントは Lightning Experience をはじめとした色々な箇所で利用できる。
      Salesforce Classic, VF, Salesforce アプリケーション, Lightning Experience ... これら動作させる環境を「コンテナ」と呼んでるっぽい。
      コンテナによってイベントを飛ばしても処理されないことがある。
      コンテナは入れ子構造にできるが、実行する Aura コンポーネントが利用できる機能は直近の親コンテナの機能だけだ。
  • コーディング概念について
    • 概念: コントローラ
      Aura コントローラはブラウザ上で動く。データ操作とか欲しければ Apex のコントローラを挟め。
    • 概念: アクション
      JavaScript で関数書く。class とかそういう言語機能のない時代の産物なので、オブジェクトプロパティとして関数を追加していく。
      「,」に注意は、後の問題にも出る。
      • コンポーネントの属性
        aura:attribute で属性宣言しなけばならず、コントローラからのアクセスも component.get('v.属性名') component.set('v.属性名', 値) しないといけない。
        この「component」 は環境の暗黙変数(暗黙とかクソやんと恨み言を吐きたい)。
        一応、「component.変数名 = 値」で突っ込みもできなくない(JavaScript Expando)けど、非推奨。
    • 概念: メソッドコールとイベント
      コントローラと画面は直接的にメソッドコールできない。やるならイベント経由。

なんというか長いうえに冗長過ぎてわかりにくい。

データモデリング

trailhead.salesforce.com

  • カスタムオブジェクトと標準オブジェクトについて
    • オブジェクトの概要
      データベーステーブルはオブジェクト、列は項目、行はレコード これ以上言うことがない。なんでこんな長く説明するんだ…
    • オブジェクトについて知る
      Salesforce ビルトインの 標準オブジェクト と、会社や業種、またはアプリ固有の カスタムオブジェクト がある。
      カスタムオブジェクトは名称の後ろに __c が追加される。カスタムオブジェクトには自動で以下の項目が追加される
      • ID : 自動生成ユニークプライマリキー (個人的にカスケード嫌いなので個の仕様は好き)
      • システム系統項目 : CreatedDate, UpdatedDate CreatedBy, UpdatedBy, OwnerId, LastModifiedDate など。システムなので自動更新項目。
      • 名前 : Name フィールド、自動採番にもできる。 カスタム項目は文字列とかテキストエリアとかも指定できるが、独特なのに Datetime(UTC でしか保存されない) と、Date (こっちはローカル日時)、数式(レコード保存時に数式を評価して自動設定される型)、複数選択項目(保存時; で文字列保存されてる型)がある。
  • オブジェクトリレーションの作成
    • リレーション系は 参照関係主従関係 がある。参照は普通のデータベーステーブルの外部キー。主従関係にすると親子関係をかなり厳密に処理する。二つ以上主従できないとか親が消えると子がすべて消えるとか(カスケード)。
  • スキーマビルダーの使用
    使い方の説明と試しだけです。

WSL から sfdx の認証を通す

前回対応した内容でいざ開発しようと思ったら、認証で行き詰ったのでその対処方法を記録する。

white-azalea.hatenablog.jp

まず、そのまま force:auth:web:login すると、失敗してしまう。
これは VSCode から行っても(Remote WSL している限りは)一緒で、これがなぜかというと、URL 認証を開始しておきながら、ブラウザを起動することができないから。

しかし、WSL には画面もクソもないわけで、まさかコンソールブラウザで認証するわけにもいかない…。
そこで、WSL の機能に頼り、Windows のアプリを WSL bash から呼び出せるように設定する。

  1. apt install xdg-utils でデスクトップアプリ由来のソフトを呼び出す機能をインストールする。WSL には GUI が無いのだから、当然入ってない。
    Debian -- sid の xdg-utils パッケージに関する詳細
  2. 適当なパスに、シェルを記述する。まぁめんどくさいので今回はユーザホーム直下に書いた。シェル名は start_chrome.sh で、中身はこんな感じ。mnt/ 以降は Windows のパスなので、ブラウザのパスを突っ込もう
    sh "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" $1:$2
  3. chmod +x start_chrome.sh で実行権限を与えとこうか。
  4. pwd で今のパスを拾っとく。今回打ったら /home/azalea だった。ここにシェルを書いたので、シェルのパスは /home/azalea/start_chrome.sh だ。
  5. .bashrc を開いて、最後に export BROWSER="/home/azalea/start_chrome.sh" と突っ込んでおく。
  6. source .bashrc を叩いて、設定を読み込む。

検証してみるにはコマンドラインxdg-open https://www.salesforce.com と打ち込んでみよう。
正しく設定されていれば、WindowsChrome が立ち上がるはずだ。

これが出来たら sfdx auth:web:login でブラウザを起動して認証しよう。

f:id:white-azalea:20210420204944p:plain

キャプチャボード導入と、録画を試す

こんなものを購入したので、色々試したメモです。

Elgato Game Capture HD60 Pro [並行輸入品]

Elgato Game Capture HD60 Pro [並行輸入品]

  • メディア: Personal Computers

これは内蔵型キャプチャボードで、USB 型も存在しています。
面倒とか、中触るの怖い人はこっち Elgato Game Capture HD60 S [ソフトウェアエンコード式キャプチャボード(日本国内正規品)] 1GC109901004 を使うと良いかも知れません。

インターフェースは PCIE なので、スロットが開いてるかどうかも確認しましょう。
因みに、留めネジは入ってないので、事前に用意しておく事を推奨します。

この内臓キャプチャボードには、IN/OUT のHDMIポートがあり、IN が録画用ソースで、OUT はパススルー出力ポートである。
パススルーというのは、録画用の処理を一切せず、IN の内容を出力するもので、こっちは完全に遅延なし。
これを利用して、OUT のHDMI をディスプレイやTVに繋げば、遅延を気にせず遊べます。(USB版もパススルーはできるはず)

インストール

まずはデバイスドライバインストールと、キャプチャソフトインストールを行います。
ダウンロードサイトはこちら

www.elgato.com

自分のキャプチャボードと、OS を選ぶと

f:id:white-azalea:20210419190223p:plain

二つのアプリが出てきます。
ダウンロードするのは右側の GAME CAPTURE の方。 (4K CAPTURE UTILITY はおそらくTVとか動画とかをキャプチャするためのツールじゃないかな…)

f:id:white-azalea:20210419190249p:plain

因みに、気づかないと凹むのはこっそり下の方に View game capture drivers here. とか書いてあるやつ。
なんでドライバがこっそりしてるんだよとは思うけど、これも入れておく。

f:id:white-azalea:20210419190457p:plain

インストールする順番は気にしなくても良いらしい。

続きを読む

Salesforce開発の基礎編1

教科書はコレ。

trailhead.salesforce.com

問題となるのは、この勉強用プラットフォームの翻訳を信用できないという所(汗
日本語だと正解選択肢が出ないとかいうバグもちらほらある。

加えて単語の訳が微妙過ぎて、同じページで同じ単語の訳が一貫してないとかいうクソ仕様まであるので、改めて先頭から見ようかと。

プラットフォーム開発の基礎 | Salesforce Trailhead

超ざっくり要約:

  1. プラットフォーム開発の開始
    Trailhead Playground という環境の作成チュートリアル
    忘れてはいけないのは、環境作成直後に「英語」に変更しておくこと。
    多分それ以外に注意点はない。
    Salesforce では、環境一つ一つを「組織」と呼んでる。「Trailhead Playground」で作成された環境も「組織」と呼ぶことがあるので注意。
  2. コーディング不要の開発
    OSS 開発でブイブイ言わせてた人のためには基本的に読み替えが出来れば理解しやすいと思う。
    • メタデータ = テーブルに関連した表示設定などの周辺設定情報
    • オブジェクト = テーブル、またはテーブルスキーマ
    • 項目 = カラム定義
    • レコード = レコード 注意点「オブジェクト」と紹介しているくせに、後述でオブジェクト操作のUIを「スキーマビルダー」とか言い出してるところ。 オブジェクトの定義内には、データの形状のほかに見せ方の定義(レイアウト、検索条件などのメタデータ)が含まれてるのが重要な点かと。
  3. Salesforce 言語によるコーディング
    開発する際によく使うフレームワーク/言語の紹介。
    • Lightning コンポーネント Salesforce は過去のアップデートで Lightning というインターフェースに移行してて、その際出てきたフレームワーク
      Lightning インターフェースに沿った画面が作れたり、Lightning 特有のコンポーネントを組み合わせることで、リッチな画面を作成しようというもの。 XML + JavaScript で書くことになるが、独自仕様と制限が多いので嫌われ気味。
    • Apex
      Salesforce で開発するとなったときの大体の場合の第一言語
      Java ライクを目指したといいつつ、Generics は実質利用不可能で、リフレクション関連も利用できない。
      Java 1.4 にかろうじて List に型が宣言できる程度だと思っておくと良いかもしれない。
      コード中に SOQL というオブジェクトにのみ適用できるクエリが書ける。
    • Visualforce
      画面作成や、外部公開ページ(非Salesforce組織ユーザ向け画面)を作る際に良く使われる候補。
      ASPJSP の流れを持った奴だと思うと分かりやすい。 尚、Visualforce のバックエンドは Apex 一択で、static 変数は JSP と違ってセッション単位にインスタンスができる。 つまり、他のユーザと static 変数の共有はしない所は勝手が違う。
  4. Salesforce Platform の拡張
    Salesforce は外部からアクセスする手段をそこそこ沢山持ってる。
    また、Heroku が Salesforce 傘下なので、Heroku 上の Postgres ←→Salesforce object をリンクするなんてこともできる。

Apex と .NET の基本 | Salesforce Trailhead

因みに .NET と聞くと Microsoft .NET を連想しそうだが、正直忘れないと地獄を見る。
これはやればやるほど分かるが「どこが .NET じゃ」と暴れるレベル。

  1. .NET の概念の Lightning プラットフォームへの対応付け
    ざっくり概要:
    • Apex はオブジェクト指向で、C# ライクな構文形態してますよ
    • データ型は大体似てますよ
    • リスト/セット/マップ 位のデータ構造は似た感じで使えますよ
    • ASP.NET と Visualforce は似てますよ(←個人的に絶対にNOと言いたい。良いところ ASP 止まりでしょう…)
    • Apex はデータと密接に連携してるので、LINQ っぽいクエリ書くけど、これはレコード専用だよ。
    • 設計パターンが互換しない(フレームワーク構造と使い方は1から慣れてね)
    • 単体テストコードで 75% 以上カバーしない場合、本番環境にリリース禁止ね♪ (← 個人的には良い仕様)
    • ソリューションファイル、プロジェクトファイル、設定ファイルがない
      (組織アップロード時にコンパイルだから)ローカルコンパイルしないし、何処に何を置くかの構造も決まってるので、こうした設定の類はありません。
      …ということにしておきましょう。厳密には sfdx というのが最近の主流で、これには設定が結構含まれる。
    • クラスライブラリがはるかに小さい…というか実質無い。
    • セキュリティの処理...サーバ上で、しかも特定組織でしか起動しなかったり、ユーザ単位でのアクセス権などが全部 Salesforce 上で完結するので、データベースの接続文字列とか不要です
    • インテグレーションについて 外部からの接続アプリが作れます。
  2. 実行コンテキストの理解
    コンテキストは「文脈」とか「状況」みたいに考えると理解しやすいです。
    Apex コードの呼び出し方(呼び出される状況)は複数パターンありますという話。
    ここでは演習として、データベーストリガを書きます。
    レコードの Insert 直前、Insert 後、更新直前…といったレコード処理の前後でコードを実行し、関連データ更新だったり保存値の変更だったり、入力チェックだったりできます。
  3. 非同期 Apex の使用
    非同期というとあれですが、別スレッドで処理を実行することを意味します。
    ケースの説明で
    • 処理するレコード件数が非常に多い
      バッチを使いましょう。
      Salesforce には ガバナ制限 という悪名高い制限があり、Apex 処理中でアクセス/更新するなどの回数/量に制限があります。
      バッチでなら一部回避できます。
    • 外部 Web サービスへのコールアウトを行う
      外部の REST API を呼んだりすることを「コールアウト」と呼んでます。
      この操作は、データベースの更新処理(update/delete/insert)後に実行できないという制限があるので、このような状況だけ非同期にするという手段を取ります。
    • Queueable Apex
      future より制限薄い実装

多分 Queable とか非同期周りは以下を見た方が良いかもしれない

keneloper.com