OmniAICreator/Qiita-1.07M huggingface dataset:
WSL1でMySQL5.7をインストール

##きっかけ等
1度苦労してインストールしても、依存関係でアンインストールしたりなど、そのときの手順を忘れたころにまたインストールしなきゃいけないときが来るのでそのときのための備忘録。エラーは人により出なかったり違う状況になったりするかもしれませんが、同じ・似た状況で悩んでいる方の参考になれば幸いです。また、その後のよくある手続きの手順も書いておきます。

##環境
```
$ cat /etc/issue
Ubuntu 18.04.5 LTS \n \l
```
<ul>
<li>WSL1 (Windows10, Ubuntu18.04)</li>
<li>これはアンインストール後の2度目のインストール時に書いていますが、前のmysql-server, mysql-client, mysql-commonは"apt remove --purge"により削除しています。また、"apt autoremove --purge"と"apt autoclean"も実行し、</li>
</ul>

##インストール
```
$ sudo apt install mysql-server mysql-client
```

##service startするがfailする問題
```
$ sudo service mysql start
 * Starting MySQL database server mysqld                                                                                                      [fail]
```

###ログを見ると、すでにmysqlのプロセスがあると言われる
```
$ sudo cat /var/log/mysql/error.log
2021-03-10T07:09:14.494776Z mysqld_safe Logging to '/var/log/mysql/error.log'.
2021-03-10T07:09:14.623660Z mysqld_safe A mysqld process already exists
```

###topで確認
```
$ top
  153 mysql     20   0   10668    776    744 S   0.0  0.0   0:00.06 mysqld_safe
  560 mysql     20   0 2332320 197076  27624 S   0.0  1.2   0:35.09 mysqld
```

###killしてみた。でも実はできてなかった。
```
$ sudo kill 153
$ sudo kill 560
$ sudo service mysql start
 * Starting MySQL database server mysqld                                                                                                      [fail]
$ top
  153 mysql     20   0   10668    776    744 S   0.0  0.0   0:00.06 mysqld_safe
  560 mysql     20   0 2332320 197076  27624 S   0.0  1.2   0:35.09 mysqld
```

##既存のmysqldプロセスを強制kill
```
$ sudo kill -9 153
$ sudo kill -9 560
```
参考：<a href="https://www.cyberciti.biz/faq/how-force-kill-process-linux/">https://www.cyberciti.biz/faq/how-force-kill-process-linux/</a>

###起動成功
```
$ sudo service mysql start
 * Starting MySQL database server mysqld                                                                                                      [ OK ]
```
特に初回インストールのときはMariaDBを入れようとしたこともあり10時間くらい格闘したが、今になって振り返ると本当の問題はこれだけだったようで。。

##rootパスワードを再設定する
少し適当な文献を見つけるのに手間取りましたが、結局、<a href="https://ryotatake.hatenablog.com/entry/2019/11/12/access_denied_for_user_rootlocalhost">このページ</a>に沿うのが良さそう。これで、"mysql -u root -p"で入れるようになりました。

```
$ sudo mysql
mysql> update mysql.user set plugin='mysql_native_password' where user='root';
mysql> update mysql.user set authentication_string='password' where user='root';
mysql> flush privileges;
```

##文字コード(utf8, utf8mb4)の設定
to be written

##mysql2 (gem) のインストール
<a href="https://qiita.com/GandT/items/bee105afe228a564a4da">こちら</a>
Nuxt.jsデプロイ、GitHub.io静的jsリソース404エラーの解決方法

## 現象

* Nuxt.jsのプロジェクトをGitHub.ioにデプロイすると、下記エラーが発生しました。

![console-404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929657/aca58618-44e9-5822-3cf9-a667590ab769.png)

* 実際にjsファイルがRepositoryに存在します。

![repository.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929657/0de0b0fb-5e32-b887-556c-63777d63546e.png)

## 原因推測

* Nuxt.jsのGenerateでのフォルダー `_nuxt` がHTTPの `content-security-policy` を行いました。セキュリティーのため、`_nuxt/*.js`ファイルのアクセスを禁止されました。

![nuxt-page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/929657/86912502-4e3e-5160-ba7d-ec889bf3a42e.png)

## 修正する方法

* `nuxt generate` 後に `Node.js` でフォルダーの名を変更します。例えば`_nuxt` -> `static`
* `nuxt.config.js`の修正も必要です。

### nuxt.config.js

```javascript
{
  // Disable server-side rendering (https://go.nuxtjs.dev/ssr-mode)
  ssr: false,
  // Target (https://go.nuxtjs.dev/config-target)
  target: 'static',
  build: {
    extend(config, { isDev }) {
      if (!isDev) {
        config.output.publicPath = './static/'
      }
  },
  router: {
    mode: 'hash'
  },
}
```

### generate

```shell
# command
nuxt generate
```

ビルドされたファイルは`dist`にあります。

### node.jsの処理

```javascript
// build/index.js
const fs = require('fs-extra')
const { resolve } = require('path')

// Rename: _nuxt to static
fs.moveSync(resolve(__dirname, '../dist/_nuxt'), resolve(__dirname, '../dist/static'))
```

```shell
// command
node build/index.js
```

### package.json修正

```json
{
  "scripts": {
    "build": "nuxt generate && node build/index.js"
  }
}
```

一つのコマンドでソールのビルドと、フォルダー名の変更になります。

```shell
// command
npm run build
```

## 備考

ソース: https://github.com/capricorncd/blog/tree/master/demos/app-website

Github Pages: https://capricorncd.github.io/blog/dist/app-website/
aタグを使ってHTMLでページ内リンクをスムーズスクロールさせる

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ HTML及び、JavaScriptの知識が増える
・ a要素を使ってHTMLでページ内リンクをスムーズスクロールさせる方法

## 例

下記の様に、ヘッダーに各コンテンツのリンク先を掲載する場合です。

![screencapture-localhost-3000-2020-12-09-11_17_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/c38832d4-12ba-6993-2b94-d8e42c078cd7.png)

## haml
リンク先にidを割り振ります。

```haml:index.haml
.container-top#HOME
.container-profile#ABOUT
.container-skill#SKILLS
.container-works#WORKS
.container-contact#CONTACT
```

ヘッダーのa要素に、href属性で先ほど割り振った各リンク先のidを書きます。

```haml:index.haml
.header
  %a(href="#HOME") HOME
  %a(href="#ABOUT") ABOUT
  %a(href="#TEXT") TEXT
  %a(href="#WORKS") WORKS
  %a(href="#CONTACT") CONTACT
```

これでaタグをクリックすると、割り当てたリンク先にスクロールしますが
瞬時にスクロールしてしまい、あまり面白みがない様に感じます。

スムーズスクロールさせるには、CSSを使うか、JavaScriptを使う2種類の方法があります。

#### html要素にscroll-behavior: smooth;を適用する

導入がとても簡単ですが、ページ内リンクが全てスムーズスクロールになってしまい、スクロール速度の微調整ができません。

```scss:index.scss
html {
  scroll-behavior: smooth;
}
```

#### JavaScriptでスムーズスクロールさせる

先程のhamlのa要素にクラスsmoothScrollを付与します。

```haml:index.haml
.header
  %a.smoothScroll(href="#HOME") HOME
  %a.smoothScroll(href="#ABOUT") ABOUT
  %a.smoothScroll(href="#TEXT") TEXT
  %a.smoothScroll(href="#WORKS") WORKS
  %a.smoothScroll(href="#CONTACT") CONTACT
```

クラスsmoothScrollがあるか判定し、ない場合は処理を中断します。

```javascript:scrpit.js
document.addEventListener("click", (e) => {
  const target = e.target;
  if (!target.classList.contains("smoothScroll")) return;
  e.preventDefault();
  const targetId = target.hash;
  document.querySelector(targetId).scrollIntoView({
    behavior: "smooth",
    block: "start",
  });
});
```

[参考](https://developer.mozilla.org/ja/docs/Web/API/Element/scrollIntoView)：どちらの方法も対応ブラウザがchromeとFirefoxにほぼ限られてしまう点には注意とのことです。
VSCodeのREST Clientで日本語がUnicodeで表示される対処法

個人的にAPI開発はVSCodeのREST Clientが使いやすいです。Postman卒業しました。
REST Clientを設定なしに使っていると、日本語のレスポンスがUnicodeで表示されてしまい何書いてるかわからないです。
そんな時はsetting.jsonで以下の設定を書きましょう。

```
"rest-client.decodeEscapedUnicodeCharacters": true
```
Cloud9IDE環境に接続できない（Cloud9 could not connect to the EC2 instance）


## 事象
cloud9でIDE環境を作成したのですが、以下のようなエラーで接続できませんでした。

Cloud9 could not connect to the EC2 instance. Please check your VPC configuration and network settings.
![Screen Shot 2020-12-09 at 13.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296083/aaa15ad3-236c-91a4-1d63-c85ba1eabbcf.png)

## 対応
### 別のリージョンに立ててみる
東京リージョンの既存VPCで作成しようとして上記エラーが出ているので、別のリージョンでVPCの設定もCloud9で作ってもらうことで解決しました。


### ルーティングを見直す
- VPCのルーティング
- ネットワークACL
- EC2にアタッチされたセキュリティグループ
などを見直します。

私の場合はインターネットゲートウェイがblackholeのステータスになっており、すでに削除されているインターネットゲートウェイを利用しようとしていたのが原因のようでした。

Cloud9のVPC設定
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/vpc-settings.html#vpc-settings-requirements-security-groups-instance-view

### EC2を再起動する
突然繋がらなくなった場合、EC2の再起動をするだけで解決する場合もあるようです。
IEでもCSSによる画像のトリミングをしたい (object-fitのIE11対応)

## はじめに
アバターなどユーザーがアップロードした画像を特定の領域内に表示したいというケースがフロントエンドの実装をやっているとちょこちょこあります。
 
そのような場合は、[object-fit](https://developer.mozilla.org/ja/docs/Web/CSS/object-fit)という素晴らしいCSSプロパティがあるので、これだけ使っていれば大体事足りるのですが、残念なことにIEはこの`object-fit`プロパティに対応していません。

**参考 [Can I use: object-fit/object-position](https://caniuse.com/object-fit)**
![css-object-fit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/059b6d0d-daa0-3f50-fd03-63eeb4426948.png)

すでにIEは非推奨ブラウザなので対応しないとできれば良いのですが、案件によってはIE11対応を求められることもあります。そういった場合にどうやったら`object-fit`みたいな実装をIEでもできるのかを本記事に記載します。

## 対応内容
同じような悩みを抱えていたエンジニアが多かったようで、素晴らしい先人が[object-fit-images](https://github.com/fregante/object-fit-images)というライブラリですでにIEの`object-fit`のPolyfill対応をしてくれているので、今回はこちらを使用します。

参考： [object-fit-images](https://github.com/fregante/object-fit-images)


1. `yarn add object-fit-images`でライブラリを追加
2. 下記のコードのように`object-fit`を利用したいimgタグに`font-family`の記述を追加します

```css
.your-favorite-image {
	object-fit: contain;/* ← これでIE以外のブラウザは対応可能*/
	font-family: 'object-fit: contain;';/* ←の記載をIEのPolyfil用に追加*/
}
```

3.`</body>`の前か、DOMの読み込みが終わったタイミングで`objectFitImages()`を呼び出します
(`objectFitImages`にセレクタを渡すことでPolyfilの対象を指定することもできます)

=> `background-image`などで`'object-fit`相当の表現ができていることを確認できます。

## 補足事項
**1.デフォルトの挙動**
`object-fit-images`はデフォルトではすべての`img`タグを対象にします

**2.`objectFitImages`の呼び出しのタイミング**
`object-fit-images`は`object-fit`のターゲットとなるElementの`src`属性 / `srcset`属性を読み取って処理を行います。
そのため、React / Vue / jQueryなど動的にDOMを生成する場合は`src`属性 / `srcset`属性が反映されたあとに`objectFitImages`の呼び出しをする必要があります。

## 最後に
DOMを動的に生成している場合は注意が必要ですが、IEでの画像対応どうしようという場合にこのライブラリを利用すると少ないコード量で実装できるので助かりました。

自分もこういう痒いところに手が届くライブラリをOSSで公開したいなと思いました。
【JS】正規表現で小文字のアルファベットのみ抜き出す方法

正規表現とtestメソッドを使うことで合致した値を抜き出すことができる。

##目次

1. [/ /とtest](#とtest)
2. [変数とtest](#変数とtest)
3. [RegExpとtest](#regexpとtest)
4. [//とexec](#とexec)
5. [//とmatch](#とmatch)



##1. / /とtest
正規表現を表す`/ /`とtestメソッドを使った方法。

```js:
str = "aBc DeF 123 !!!"

res = []
for ( elem of str ){
    if( /[a-z]/.test(elem) ){
      res.push(elem)
    }
}

console.log(res) 
//["a", "c", "e"]
```

・`/[a-z]/.test(値)`
値がアルファベットの小文字（a ~ z）ならtrueを返す。

・testメソッド
`正規表現.test(値)`　
結果はboolean。値が正規表現に一致していればtrueを返す。

・正規表現
`/ /`で囲んだ中身が正規表現となる。

・`[a-z]`
a ~ zのいずれか１文字。

・`for( a of arr )`
arrから一文字づつ抜き出し変数aに代入。
`for(let i = 0; i < arr.length; i++){ arr[i] }`と同じ。



<br>
##2. 変数とtest
No.1の正規表現を変数に置き換えることもできる。

```js:
str = "aBc DeF 123 !!!"
res = []

re = /[a-z]/
for ( elem of str ){
    if( re.test(elem) ){
        res.push(elem)
    }
}

console.log(res)
//["a", "c", "e"]
```

reはReguler Expression（正規表現）の略。



<br>
##3. RegExpとtest
`/ /`を`RegExp(" ")`に置き換えても正規表現となる。

```js:
str = "aBc DeF 123 !!!"

res = []
for ( elem of str ){
    if( RegExp("[a-z]").test(elem) ){
        res.push(elem)
    }
}

console.log(res)
//["a", "c", "e"]
```

<br>
`RegExp("[a-z]")` は `/[a-z]/` と同じ。


```js:RegExpの中身
console.log(RegExp("[a-z]"))

/*
/[a-z]/
*/
```

`RegExp("[a-z]")`も`/[a-z]/`と同様に変数に代入できる。



<br>
##4. //とexec
testメソッドではなくexecメソッドで同様の処理を行うこともできる。

`正規表現.exec(値)`
値が正規表現に一致すれば、その値を返す。一致しなければnullを返す。

これと、`if(null)`の **null は false になる**ことを利用する。また、`if(存在する値)`はtrueになる。

```js:
str = "aBc DeF 123 !!!"
res = []

for ( elem of str ){
    if( /[a-z]/.exec(elem) ){
        res.push(elem)
    }
}


console.log(res)
// ["a", "c", "e"]
```

`/[a-z]/.exec(elem)`がsyntaxエラーになる場合は、`/[a-z]/`を変数に代入するか、`RegExp("[a-z]".exec(elem))`とすれば正規表現として認識される。



<br>
##5. //とmatch
execメソッドとよく似たmatchメソッドを使っても実現できる。

`値.match(正規表現)`　＝　`正規表現.exec(値)`

値が正規表現に一致すればその値を、一致しなければnullを返す。

```js:
str = "aBc DeF 123 !!!"

res = []
for( elem of str ){
    if( elem.match(/[a-z]/) ){
        res.push(elem)
    }
}

console.log(res)
//["a", "c", "e"]
```


<br>
今回は小文字のアルファベットを抜き出したが、正規表現を変更すれば、数値のみ抜き出したり、パターンが一致する場合に抜き出すことができる。

<br>
###追記
@il9437さんよりシンプルな記述を教えていただきました。

```js:
str = "aBc DeF 123 !!!"

res = str.match(/[a-z]/g)
console.log(res)  // ["a", "c", "e"]
```

・`/[a-z]/g`
フラグでg (global)をつけると、2番目、３番目にマッチする部分も検索する。

ない場合は初回で終了。
VirtualBoxについて簡単に調べてみた

#VirtualBoxとは
VirtualBoxとは正式名称を<b>Oracle VM VirtualBox ( オラクル　ブイエム　バーチャルボックス )</b>と言い、オラクル社が開発を行っている`仮装化ソフトウェア`です。

`仮想化`とは、1つのパソコンに複数のOSを同居させる技術になります。１つのパソコンを２つに見せかける。まさに『分身の術』のような技術。

VirtualBoxを使えばmacOS と Windows が一緒に使えます。
そんなソフトが無料で使えるとあって人気が高いものになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/0a046ccc-82d2-019a-440d-185d4efd7114.png)



###[VirtualBox](https://www.virtualbox.org　)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/354ce8b0-ec4c-fd17-3755-6e201dd56187.png)




##参考
https://www.linuxacademy.ne.jp/lablog/infrastructure/287
https://www.sejuku.net/blog/72833
GithubActionsでRailsのテストカバレッジをレポートする

## はじめに

Railsでカバレッジ計測する場合に一番使われているgemは恐らく[simplecov](https://github.com/simplecov-ruby/simplecov)ではないかと思います。
simplecovでは、デフォルト設定の状態でhtmlのレポートファイルを生成してくれて大変見やすいのですが、コードレビューの度に目視でチェックというのはなかなか出来ないですよね。
テストカバレッジを見やすく手段の一つとして、[Code Climate](https://codeclimate.com/)等のSaaSを利用するという方法もありますが、ユーザー数やリポジトリ数に比例して費用が大きくなっていきます。

そこで今回は、そこまで詳細なレポートは不要だけどコードレビュー時に全体のテストカバレッジを分かりやすく表示したいというケースで有用なアクションを作ったので紹介します。

## 設定方法

```yaml
name: Tests
on:
  pull_request:

jobs:
  build:
    steps:
      # テストの事前準備色々...
      
      - name: Test
        run: bundle exec rspec

      - name: Simplecov Report
        uses: aki77/simplecov-report-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # 以下はデフォルト設定
          # resultPath: coverage/.last_run.json
          # failedThreshold: 90
      
      # テストカバレッジの詳細を確認したい時の為
      - name: Archive coverage artifacts
        uses: actions/upload-artifact@v2
        with:
          name: coverage
          path: coverage
        if: always()
```

## 動作解説

上記の設定をすることでpull_requestイベント毎にテストカバレッジがコメント欄にレポートされるようになります。

![Demo](https://i.gyazo.com/c4e572c91fe8048c95392ea3ddce79f5.png)

細かい考慮点としては以下があります。

- 同一PR内でテストカバレッジに変化がない場合は何もしない
- 同一PR内でテストカバレッジに変化があった場合は以前のコメントを削除して新しくコメントする
- テストカバレッジが設定した閾値（`failedThreshold`）を下回った場合には失敗する

## Marketplace

[Simplecov Report · Actions · GitHub Marketplace · GitHub](https://github.com/marketplace/actions/simplecov-report)

良かったら使ってみてください。
Rails ログイン機能の実装


<h2>ログイン機能を実装する</h2>

ログイン機能では、ユーザーがログインするためのフォーム画面を表示し、そこから送られてきた情報を元に
ユーザーを認証する。さらに、ログアウトも提供する。

Railsでログイン機能を実装する際は、<strong>ログインする=「セッションというリソースを作る」</strong>と捉えて、
SessionsControllerと言う名前でコントローラを作ることがよく行われる。
コントローラに追加したいアクションは

<strong><i>ログインフォームを表示する場合</strong>   HTTPメソッド・・・GET  　　URL・・・/login  アクション名・・・new

<strong><i>フォームから送られてきた
情報を元にログインを行う場合</strong>            HTTPメソッド・・・POST 　　URL・・・/login  アクション名・・・create

<strong><i>ログアウトを行う場合</strong>           HTTPメソッド・・・DELETE  　　URL・・・/logout  アクション名・・・destroy

<h3>ログインのフォームを表示する</h3>

SessionsControllerを作っていく。このときコントローラと一緒にnewアクションとビューも作る。

```$ bin/rails g controller Sessions new```

ジェネレータによってコントローラやビューが作られてルーティングも自動的に定義される。

```ruby:config/routes.rb

Rails.application.routes.draw do
  get 'sessions/new'

```

しかし今回は、ログインフォームを表示するアクションのURLは/loginにしたいので以下の設定に書き直します。

```ruby:config/routes.rb

Rails.application.routes.draw do
  get '/login', to: 'sessions#new'

```

これでログインフォームを表示するアクションのURLが/loginになった。
次はhtml.slimファイルを編集して画面にログインフォームを表示するようにします。

```ruby:app/views/sessions/new.html.slim

h1 ログイン

= form_with scope: :session, local: true do |f|
  .form-group
     = f.label :email, 'メールアドレス'
     = f.text_field :email, class: 'form-control', id: 'session_email'
  .form-group
     = f.label :password, 'パスワード'
     = f.password_field :password, class: 'form-control', id: 'session_password'
  = f.submit 'ログインする', class: 'btn btn-primary'

```

これでログインフォーム画面の作成が完了しました。
[Flutter]GoogleSignInのsignInSilentlyの例外がキャッチできない。

# はじめに
**この記事はFlutter初心者の私がFlutter初心者に向けて書いています。**

Flutterにてアプリを製作中です。
タイトル通りですが、ほうぼうで推奨されている方法でやっていたらハチャメチャに躓いたので投稿します。

# 何が起こったのか
下記のように怒られます。
>
Exception has occurred.
PlatformException (PlatformException(sign_in_required, com.google.android.gms.common.api.ApiException: 4: 4: , null, null))

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662111/00f77dde-9fdb-d2ed-eec3-0699846fffa5.png)

かと言ってtry catchも出来ません。

# 結論
恐らく下記のように記述しているかと思いますが


``` dart:改善前
googleCurrentUser ??= await _googleSignIn.signInSilently();
```

``` dart:改善後
googleCurrentUser ??= await _googleSignIn.signInSilently(suppressErrors: false);
```

`suppressErrors: false`を渡してあげることでtry catchでしっかりキャッチできるようになります。
デフォルトは`true`です。

# 理由
恐らくデバッグ環境でしか発生しないと思います。
signInSilentlyのexceptionの握り潰し方がひどいんだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662111/56b5f114-a8c1-fc28-8e94-afe2dc919aec.png)

# 他の解決方法
もう一つの方法としては、IDE内部の`BREAKPOINTS`の`Uncaught Exceptions`のチェックを外すことだと思いますが、おすすめしません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662111/b4a59f60-5913-09f8-942a-fc4595a02abf.png)


# 参考
https://github.com/flutter/flutter/issues/28430#issuecomment-484199365
【Stereo Depth】iResNet : Reconstruction Errorを計算してRefinement

<h1>Learning for Disparity Estimation through Feature Constancy</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/8ddc8243-2ca3-6ad7-a65b-8e70681ee1b9.png)

右と左の画像から得た特徴量からCorrelationをしてCost-Volumeを作りInitial Dispaityを求める所までは従来研究と同じ。

<h1>新規性</h1>
<h2>Reconstruction Error</h2>
赤のlayerがReconstruction Errorといい、推定したDisparityを使って画像をWarpすることで、逆の画像を推定(Reconstruction)する。Reconstructされた画像の精度をSAD(Sum of Absolute Difference)やSSIM(Structure Similarity)を計算する事で間接的にDisparityのErrorを検出する。


<h2>Refined Disparity</h2>
Refined Disparity(黄色) = Initial Disparity(緑) + Residual(黒)で定義される。

Errorの差分(Residual)を計算するようにネットワークを構成する事でInitial Disparityを修正して最終的なDisparity Map(Refined Disparity)を得られる。

<h1>結論</h1>
・Reconstruction Errorを計算してResidual(Disparityの差分)を求めることで、より正確なDisparityを推定することが出来たそうだ。

<h1>参考文献</h1>
Learning for Disparity Estimation through Feature Constancy
https://arxiv.org/pdf/1712.01039.pdf
OpenProject　バックログ設定での失敗

### 症状

かんばん（Task boad）でのエラーが発生。
かんばんが追加できなくなりました。

以下の警告が表示される。
バージョン親ストーリーの〜〜〜日本語約はややおかしいけど、
概要は、親ストーリーのバージョンに合わせよというもの。
しかし、読んでみてもバージョンを設定する所もないので意味が分からない状態になる。

![スクリーンショット 2020-12-09 12.19.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/a1071538-cc49-d161-abd1-c0d2749b8f26.png)

### 原因

「システム設定」ー＞「バックログ」を変更していたこと。

### 解決方法

設定をもとに戻した。

### 発生理由

↓以下画像赤枠部分、このような設定入力部品の知識がなかったことによる。
「Story types」は選択中のものが「Story types」として扱われるということに気づかなかった。
そのため設定を変更した事にも意識が及んでいなかった。

![スクリーンショット 2020-12-09 12.10.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/e37eca42-5525-ea3c-8a81-97d5887f0f5e.png)

↓個別に選択できる。
![スクリーンショット 2020-12-09 12.18.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/522eb73c-58c5-6039-1fa9-767b737ad7d2.png)

### 考察

不慣れなシステム設定を不用意に触らないというのは当然の事として知れ渡っているが、マウスでクリック操作して「その部分が変更された」という意識が持てない事態が発生して見過ごされてしまった。
防ぐには変更された事を明示するのが良いと思われる。
一般的なGUIであれば、利用者によっては不要である事も多く、このケースにおいても変更を明示する機能が必要なほど珍しいGUIなのかというと、疑問がでてくる。

コストを掛けないヒントを明記する程度があればよいのではないだろうか。
Salesforce カスタムオブジェクトにプロセスを表示させる

# はじめに

Salesforce標準の商談やリード、ケースの進捗状況が一目でわかるプロセス（フェーズ）を、カスタムオブジェクトでも作りたい！

## 手順
#### １．カスタムオブジェクトにフェーズ項目を作成する。
プロジェクトオブジェクトに「進捗状況」（選択リスト）項目を作成し、
・要件定義
・設計
・デザイン
・製造
・テスト
・リリース
・(顧客)受入テスト
をvalueとして作成。

#### ２．パスの設定
**[設定][パス設定]**からパスを有効化、新規作成し、先ほどのカスタムオブジェクトと選択リスト項目を指定します。
必要があれば**[項目][成功へのガイダンス][お祝い]**を編集し完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941408/b1648246-9300-62a9-d9ea-0a3bacf1cca9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941408/d7ab1ec0-0423-ead3-3946-699d19f84671.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941408/8c8b12bb-e41b-d70c-b6bc-b0c71db5cda7.png)

#### ３.Lightningの編集
**[Lightningアプリケーションビルダー]**で新規→レコードページを作成し、任意のオブジェクトやAPI参照名を設定。コンポーネントに「パス」をドラッグ。
保存してLightningページを有効化して完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941408/0c12f9d9-e4e3-0833-b07b-6f14bbe9216e.png)

####４.確認
レイアウトに反映されている確認する。お祝い機能でクラッカーが散るとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941408/a293c894-9181-6d28-dc0d-718ac89eae56.png)
学習意欲皆無のゾンビ状態からインフラエンジニアにスキルチェンジするまでの話

:sparkles:[LITALICO Engineers Advent Calendar 2020](https://qiita.com/advent-calendar/2020/litalico):sparkles:

11日目を担当するのは
インフラエンジニアとして今年10月に入社しました、@3939_ohagiです。

## はじめに
わたしにはADHDという生まれつきの障害と、うつ病を抱えています。
障害者手帳3級も保有しています。
現在うつは寛解しており、ADHDともまぁまぁ仲良くやっている28歳です。
入社と同じタイミングで通信制大学に入学しまして、大学生でもあります。

LITALICOで3社目となりますが、インフラの経験はごく浅く、
ゴリゴリのアラサーながら育成枠としてここにいます。

なぜここまでオープンに書くかというと、「LITALICOだから」の一言に尽きます。
障害への理解はもちろんのこと、技術面に関しても馬鹿にするような人はいないので安心してさらけ出せます。エイヤッ

LITALICOについてや、エンジニアチームの考え方については
こちらをご覧いただくとお分かりいただけると思います。

- [LITALICOコーポレートサイト](https://litalico.jp/)
- @kamesenninさんの「[エンジニア採用面接での「質問項目」と「意図」を公開する](https://qiita.com/kamesennin/items/fc8242f7c395b828f650)」（昨年のアドベントカレンダーで特に好評だった記事です！）

これから先は学習意欲皆無のゾンビだったわたしが、
インフラエンジニアにスキルチェンジするまでの話です:information_desk_person:

## この記事で得られること
「こんなやつもいるのか...自分もちょっと頑張ろう」という気がわきます。（たぶん）

## 高卒でSIerに就職

高卒でSIerに就職し、主に金融系プロジェクトにいました。
7年務めましたが、自分が楽しいと思える業務に出会えずプロジェクトも転々としたので、尖ったスキルを持たないまま20代後半に。
この頃は学習意欲はほぼ皆無で、ほぼすべて諦めた状態でした。

話すと長くなるので割愛しますが、
20歳から患っていたうつ病が悪化し逃げるように1社目を退職。
ADHDは24歳のときに診断され、発達障害について情報収集するなかで「[LITALICO 発達ナビ](https://h-navi.jp/)」を通してLITALICOを知りました。

## 半年のフリーター生活で自己肯定感を取り戻す
1社目退職後は半年ほど美容系求人ライターのバイトをし、
失われていた自己肯定感を少しずつ取り戻し、憧れていたWebエンジニアになろうと決心。
当時Progateが脚光を浴びていたので、とりあえず一通りやり、
運良く自社サービスを運営する広告代理店に採用され、新しいキャリアがスタートしました。

## 気がつけばインフラへ
広告代理店なので、DM作成からSEO対策やアフィリエイト、インフルエンサーマーケティングなどありとあらゆる広告業務に携わりました。
同時に今までまったく触れていなかったWeb業界の知識を身につけることは想像以上に過酷で、
前までCOBOLやVBを触っていたので本当に浦島太郎のような気分でした。
（正直にいうと、ここに転職したて2年前はSSHもわかっていませんでした。）

開発者としてはまったく芽が出なかった中、会社の方針が変わり社内のエンジニアはPMやPMOとして活躍を求められ、わたしもとある自動車メディアサイトのPMOとなります。
インフラのみ一部内製だったため、ベンダーコントロールをする傍らでAWSにふれるようになりました。

Linuxコマンドも全然わからない状態でしたが、手動デプロイだったために触るほかなく、半べそかきながらどうにかこうにか食らいつき、気がつくと半年でサーバー差し替えなどの作業手順書を作成・レビューができるまでに。Dockerでの基本的な操作もできるようになっていました。
AWSはネットワークが全然わからないながらもパズルのように感じられ、動いたときの達成感もありました。

苦節8年。ようやく、「やった分だけ成果が目に見える業務」に巡り会えた気がしました。

## コロナ禍で気がついた、自分の恵まれた環境

仕事では徐々にインフラの整備もベンダーに依頼をしたことと
CI/CD化したことで手が空きだしており、新しいことを吸収できる場面が減っていました。

色々なことを考える時間が増え、唐突に「あ、大学で勉強しよう」と思いつきます。
元々強烈な学歴コンプレックスがあったのと、ITエンジニアとしてこれから先も食べていくには教養が必要だということも痛感していたのです。

そのうえ、コロナ禍で病院勤務している友人や、出勤せざるを得ない業種の家族を見て
目標もなくダラダラと自宅勤務をしている自分が恥ずかしく感じていました。

比較的恵まれた環境の業種だからこそ、技術で貢献できることがあるはず。
学校にいきながらインフラエンジニアとしてもキャリアが積めそうな場所。
そしてなにより社会貢献度の高い会社。
間違いなく、LITALICO一択でした。今の自分なら挑めるかもしれないと感じたのです。

## インフラエンジニアとして1から学びだす

インフラ知識はひよっこながらも、PMOとのしての経験を大きく買っていただき
晴れてLITALICOの一員となりました。
入社までに時間があったので、LinuC レベル1の101を取得。
前職で触れてきたインフラの範囲は上流レイヤーのみだったので、
現在はAWSでの基礎的なネットワーク構築の方法や低レイヤー（特にTCP/IP）について勉強をしている日々です。

## 最後に
ここまでお読みいただきありがとうございます:joy:

自己肯定感が低く、技術スキルも未熟なわたしがなぜ9年もITエンジニアをやっているか。
9年間のうち7年間はITエンジニアとは名乗れない時間を過ごしてきたことを後悔しているからです。
8年目にしてようやくスタートラインに立てており、思い切って行動することで自分の人生をやり直せることを知りました。
アラサーだし、高卒だし、障害もあるし....と卑屈になっていた時間も、自分を認める中で必要な時間でした。

だからこそ、「つらかったね、しんどかったね。でも今が一番若いし、できるできる！（しらんけど!）」と自分に声をかけ、とにかく止まらず動き続けています。
技術者として社会貢献できるにはまだ時間がかかるかもしれませんが、這いつくばって進んだ先で
少しでも誰かを照らせるように精進していきます。

明日は @ti_aiutoさんの記事となります！お楽しみに:sunny:
iPhone12にも搭載されたLiDARセンサーで遠隔測定、測量UNITYアプリケーションの研究開発

**iPhone12にも搭載されたLiDARセンサーで遠隔測定、測量UNITYアプリケーションの研究開発**

IntelのLiDARセンサーを利用して遠隔で物体の長さを測定するアプリケーションを開発しました。Intel RealSense LiDAR Camera L515で深度情報を測定し、UNITYのアプリケーションで長さを表示します。

![iPhone12にも搭載されたLiDARセンサーで遠隔測定、測量UNITYアプリケーションの研究開発.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332191/0f0fe40b-88a2-2771-5b21-ac00c2370143.jpeg)


**クライアントの課題は危険な場所での測定や測定業務を自動化して人員不足を解決**

iPad ProにLiDARセンサーが搭載されたブログ記事を配信したところ数多くの問い合わせをいただきました。iPhone12にも搭載され注目を集めている技術です。

**IPAD PROに「LIDARスキャナ」が搭載。3D認識の向上でAR開発が加速。**

危険が伴う場所での遠隔測定、人員不足のために測定業務を自動化したいという課題でのお問い合わせありました。そこで弊社ではiPad ProやiPhone12より精度の高いIntel RealSense LiDAR Camera L515を利用して遠隔測定アプリケーションを作成する研究開発をしました。


**LiDARスキャナとは**

LiDARスキャナの LiDAR は「Light Detection and Ranging」略で、光で距離を測定する技術のことです。近年の自動運転技術でもLiDARは注目されています。市街地における自動運転にはLiDARが必要不可欠と言われるほどの技術です。


**LiDARセンサーアプリケーション特徴**

LiDARセンサーで物体を３Dスキャンします。
３Dスキャンしたポイントクラウド（点群データ）はUNITYアプリに表示されます。
Unityアプリケーションで物体との距離、測定したい個所を測定します。

下記の研究開発では、実測値とLiDARセンサーでの計測値の誤差がどのくらいかを測定しました。
500mm離れた場合の誤差は5mmという結果になりました。しかしIntel RealSense LiDAR Camera L515の仕様書では1mmの誤差まで測定できるとありますのでアプリケーションの改善が必要です。

Intel RealSense LiDAR Camera L515を利用してUnityアプリケーションで測定（※）

Intel RealSense LiDAR Camera L515は高解像度/高精度の深度データを必要とする屋内/屋外アプリケーションの開発に重点をおいた距離測定デプスカメラです。

下記の動画を測定方法をご覧にしてください。

https://www.youtube.com/watch?v=dIesUtSxvlY
LiDARセンサーアプリケーションの改善ポイント

LiDARで３Dスキャンしたポイントクラウド（点群データ）をより高解像度にします。
測定する開始点と終了点をの精度をあげます。さらに自動測定にします。

**開発期間**
期間：2020年10月~2020年11月
規模：2人月

**対応範囲**
要件定義

* 弊社で要件定義をまとめました。

**基本設計・詳細設計**

* 基本設計書と詳細設計書を作成して業務の実用と距離測定ロジックをあわせて設計して実施しました

**コーデイング**

* 弊社でUnityコーデイング規約に沿ってコーデイングしました

**システムテスト**

* 単体テスト距離測定モジュールをテスト実施しました

**LiDARセンサーアプリ開発の技術**

* 開発言語：Unity

**今後のアップデート**

* 現在誤差は5㎜となります。Intel RealSense LiDAR Camera L515の仕様書では1mmまでの誤差となっています。調査して改善版をアップデートします


**参考実績**

７セグメントディスプレイのデジタル数字認識OCRモジュール開発（SSOCR)
【Rails】 inverse ofオプションについて

rubocopを実行していたらRails/InverseOfという形で怒られたので、inverse_ofとはなんぞやというところから分かったことをアウトプットしていきたいと思います。

## inverse_ofオプションとは
Railsガイドによると、双方向の関連付けに使われ、rails4.1以降では指定せずともrails側が自動でつけてくれるが、自分で定義した関連には明示的にオプションを付ける必要があるとのこと。つけないと意図しない挙動をする可能性があるようです。

**双方向の関連付けについて詳しくはこちら**
https://railsguides.jp/association_basics.html#%E5%8F%8C%E6%96%B9%E5%90%91%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91

## 今回扱う関連モデル
簡潔にするため、必要ないオプションは省略しています。また、この後出てくるpryでの実行結果においてもSQLの出力は省略してあります。

```ruby:user.rb
has_many :sold_tickets, class_name: 'Ticket', foreign_key: 'seller_id'
```
```ruby:ticket.rb
belongs_to :seller, class_name: 'User'
```

## inverse_ofオプションなしの場合
コンソールを立ち上げて、ニックネームがさかいのuserを取得します。

```ruby=
pry(main)> user = User.find(1)
=> #<User id: 1, email: "aaa@example.com", nickname: "さかい", created_at: "2020-11-19 21:18:56", updated_at: "2020-12-06 04:29:04">
```

次にさかいの出品したチケットを1枚取得します。

```ruby
pry(main)> ticket = user.sold_tickets.first
=> #<Ticket:0x00007fd018ff31e8
```

ニックネームを酒井に変更します。

```bash=
pry(main)> user.nickname = "酒井"
=> "酒井"
```
すると、同じオブジェクトを参照しているはずのticket.seller.nicknameでは値が書き換わっていません。

```ruby
pry(main)> user.nickname == ticket.seller.nickname
=> false
pry(main)> ticket.seller.nickname
=> "さかい"
```
これは別々のオブジェクトが生成されているためです。

```ruby
pry(main)> user.equal? ticket.seller
=> false
```
このままでは、意図しないエラーが起きてしまう可能性がありそうです。
さあここでinverse_ofオプションの出番です。

## inverse_ofオプションありの場合

```ruby:user.rb
has_many :sold_tickets, class_name: 'Ticket', foreign_key: 'seller_id', inverse_of : 'seller'
```
同じようにuserとticketを定義し、ニックネームを酒井に変更します。

```ruby
pry(main)> user = User.find(1)
=> #<User id: 1, email: "aaa@example.com", nickname: "さかい", created_at: "2020-11-19 21:18:56", updated_at: "2020-12-06 04:29:04">

pry(main)> ticket = user.sold_tickets.first
=> #<Ticket:0x00007fd018ff31e8

pry(main)> user.nickname = "酒井"
=> "酒井"
```
すると、先程とは違い同一のオブジェクトを参照し、値が書き換わっていることがわかります。つまり、inverse_ofは同一のオブジェクトを参照させるためのオプションだったわけです。

```ruby
pry(main)> user.nickname == ticket.seller.nickname
=> true
pry(main)> ticket.seller.nickname
=> "酒井"
pry(main)> user.equal? ticket.seller
=> true
```
ちなみに、Ticketモデルにinverse_ofオプションをつけても同一のオブジェクトを参照しません。

**関連定義**

```ruby:user.rb
has_many :sold_tickets, class_name: 'Ticket', foreign_key: 'seller_id'
```

```ruby:ticket.rb
belongs_to :seller, class_name: 'User', inverse_of: 'sold_tickets' # 追記
```
**実行結果**

```bash
pry(main)> user.nickname == ticket.seller.nickname
=> false
pry(main)> user.equal? ticket.seller
=> false
```
inverse_of 'seller'の「**seller**」はUserクラスのインスタンスのオブジェクトはsellerメソッドで取得したオブジェクトと同一のものとしますよという意味だったんですね。

以上になります。何かまちがっている箇所等ありましたらご指摘ください。
agora.io Video SDK for Flutter クイックスタートガイド  (2020-12-09 改訂版)

# はじめに

本記事は 2020-09-08 の記事「[agora.io Video SDK for Flutter クイックスタートガイド](https://qiita.com/v-cube/items/f2c8d2c5ff8740bd0f3f)」 の改訂版となります。

# 概要

agora.io では Flutter を利用した開発が可能です。

Flutter は Google 社が開発した Android/iOS 向けクロスプラットフォームのフレームワークで、「Dart」というオブジェクト指向言語を使って開発します。

agora.io の [Download Center](https://docs.agora.io/en/All/downloads?platform=Flutter) では、Flutter 用のリンクが下図のように表示されますが、こちらは pub.dev に公開している SDK パッケージへのリンクとなっています。
※ 2020-12-09 時点

![downloadpage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/2ec6cfdd-4ef5-7828-ec96-704b62fb7fd4.png)


現在、Flutter サンプルデモは以下のリンクから入手できます。

* https://github.com/AgoraIO-Community/Agora-Flutter-Quickstart
* https://github.com/AgoraIO/Flutter-SDK

1 つ目はライブブロードキャスティングアプリのサンプルが収録されており、ビルド方法は[別記事](https://qiita.com/v-cube/items/f2c8d2c5ff8740bd0f3f)で紹介しています。
2 つ目は 1 対 1 のビデオチャットアプリのサンプルが収録されており、本記事はこちらのビルド方法を紹介します。


# ビルド方法

※ 予め Flutter を開発環境に導入してください。
https://flutter.dev/docs/get-started/install

1.[Flutter-SDK](https://github.com/AgoraIO/Flutter-SDK) をダウンロード
2.ファイルを展開し example/lib/config へ移動
3.agora.config.dart を開き、各項目を以下に沿って記入します:

■ appId: App ID を入力
■ token: token を入力 (使わない場合は、空文字列を記載)
■ channelId: デフォルトのチャンネル名を指定 (空文字列の場合、入室前に指定する必要があります)
■ uid: uid を指定 (数値型で入力すること。0 と指定した場合、uid はランダムとなります)
■ stringUid: デフォルトの文字列型 uid を指定 (空文字列の場合、特定の場面で入室前に指定する必要があります)

![flutter_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/ebdc4a37-730a-2bda-207a-375d5266e15b.png)

4.example/lib に戻り、実機ビルド & アプリ起動
※ iOS 用にビルドする場合、 examples/ios/ 内の xCode プロジェクトを開き Signing & Capabilities の設定を一通り行ってからビルドしてください。

```bash
$ flutter run
```


# アプリの画面

ビルドに成功するとアプリが起動します。
![IMG_0286.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/6339c6c1-483d-c2a6-d05a-7b18e7846b5b.png)

JoinChannelVideo のテスト。相手が入室すると左上に映像が表示されます。
![IMG_0287.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/6ce5c92f-3700-91ec-e0a8-e5fc9e4f7805.png)


#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=48e1fcf17ed8e457e2cf)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=48e1fcf17ed8e457e2cf)
influxDBをgoから操作する時はinfluxQLは使えないので注意

# GoからinfluxDBを扱う時に気をつけること
[influxDB](https://www.influxdata.com/)のリファレンスにはSQLライクな構文が使えると書いてあった。(influxQL)
しかし、公式の[Go-client](https://github.com/influxdata/influxdb-client-go)にはinfluxQLを使用する方法がないらしい。[参考](https://www.magata.net/memo/index_edit.php?Go%A4%AB%A4%E9InfluxDB%A4%CB%A5%A2%A5%AF%A5%BB%A5%B9%A4%B9%A4%EB)
私も見つけられなかった。

よって、SQLライクな構文は使用できず、[Flux構文](https://docs.influxdata.com/influxdb/v2.0/query-data/get-started/)を使用することになる。
公式には以下のように書いてある。

```
import "experimental/geo"

sampleGeoData
  |> geo.filterRows(
    region: {lat: 30.04, lon: 31.23, radius: 200.0},
    strict: true
  )
```

実はこれ、`import "experimental/geo"`も含めてflux queryとなっている。
つまり、go-clientでは以下のように書く。

```
_, _ := queryAPI.Query(
    context.Background(),
    `
    import "experimental/geo"

    |> geo.filterRows(
        region: {lat: 30.04, lon: 31.23, radius: 200.0},
        strict: true
    )
    `,
)
```

そう。まさかのqueryの中でimportするのである。
これには少々びっくりした。(jsxを思い出す)

# 終わりに
短い内容になってしまったが、知見の置き場ということで、まあ良いよね...
Rubyでの「文字列型(String)と整数型(integer)について」

# 最初に

**カレンダー企画2020の9日目**
プログラミングの勉強を始めて3ヵ月程経ったので学んだことのメモをアウトプットとして記事に残します。
これからプログラミングの世界に入る人の手助けになれたら嬉しい限りです。
間違っていたり、言葉が違っていたり、誤解されるような言葉があったら教えてください^^
言葉を長々と読みづらかったら申し訳ありません。少しずつなれてがんばります。

## Rubyでの「文字列型（String）と整数型（integer）について」

Rubyには色々型があります。
その中の2つをまとめます。

```ruby:demo.rb
puts 8
puts "8"
```

このようにして出力を行うと

```Terminal:ターミナル
$ ruby demo.rb
8
8
```

となります。
一見ターミナル上ではとくに変わりがないと感じますね！
実はこの時点ですでに違う扱いになっているのです。
demo.rbでの違いは（""）これで囲まれているか否かですね。

囲まれてない方 `puts 8`の8は整数型となります。
囲まれている方 `puts "8"`の8は文字列型となります。

違いがわかるように少しrbファイルを変更します。

```ruby:demo.rb
puts 8 + 8
puts "8 + 8"
puts "8" + "8"
```

同様に実行すると、、、

```Terminal:ターミナル
$ ruby demo.rb
16
8 + 8
88
```

上記の結果になる！
1番目：数字として認識されているので足し算が行われてその結果が出力されます。
2番目：文字として認識さているのでそのまま出力される。（数字として認識にはならないので計算はされない）
3番目：8という文字と8という文字を +（この時「つなぐ」意味になる）した結果が出力される

少し違いが分かりましたか？
今後コードを記述する時にこの違いが大事になります。

数字として認識させたいのか？
文字として認識させたいのか？
それによって使う型が変わって来るということです！


これは例では数字でしたがもちろん文字でも使えます！

```ruby:demo.rb
puts "tanaka" + "tarou"
```

```Terminal:ターミナル
$ ruby demo.rb
tanakatarou
```

となります。このように苗字と名前を繋げて表示できます。
私はアプリケーション作成の時にこれはよく使いました！

何かの会員登録とかをする時に姓と名を別々で入力することありませんか？
それを一括表示させる時にこれを応用すると綺麗にできます。


## 最後に

初期の段階で私はこれを理解したつもりになっていてアプリケーションを作成している時に躓いたのを覚えています。今整数型？文字列型？どっちが使えば効率的なのか？？みたいに^^;
なのでまとめて自分なりのメモとして残しておきます^^
中間層数を増やすとむしろ表現能力が減ってしまう？ニューラルネットワークの理論論文について解説する

#はじめに

本記事は論文"[Maximum Expressive Number of Threshold Neural Networks](https://ieeexplore.ieee.org/document/9394373)"の解説です。

内容は、活性化関数がthreshold関数のニューラルネットワークのデータ表現能力に関する論文で、多層パーセプトロンにおける最大表現数(Maximum Expressive Number)の一般解を求めたものになります。

発表スライドは[YouTube](https://www.youtube.com/watch?v=qCeBT06rX0Y&list=PLelMKv4XRW6Y7blIHZYocG1_PEfVxKMM8&index=7)で公開されています。

活性化関数がReLUの場合は[こちらの記事](https://qiita.com/nekonibox/items/00426281e45714a48f23)にまとめてあります。


#データ表現能力とは
ニューラルネットワークにおけるデータ表現能力とは、学習を行う前に決定しなければならないパラメータ[^1]、すなわちハイパーパラメータを固定したニューラルネットワークに対して、どの程度複雑な訓練データを表現できるのかという指標です。

[^1]: 中間ニューロン数、活性化関数など。

データ表現能力が高いほどより複雑な訓練データを用いて学習を行うことができますが、訓練データの複雑さに対してデータ表現能力が高すぎると過学習を引き起こす可能性があります。すなわち、データ表現能力は学習データの複雑さに合ったハイパーパラメータを決定するための1つの指標となりうるということです。

本記事ではこれらの指標のうち、データ数を基準に定義された"表現数"に着目します。


##表現数
表現数を簡単に説明すると以下のような定義になります。

>Nを自然数とする。
>ニューロン数を固定した**ニューラルネットワークが表現数Nを持つ**とは、以下を満たすことである。
>>任意のN個の訓練データに対して、その全てのデータの入出力とニューラルネットワークの入出力が一致するようなニューラルネットワークの重み値、バイアス値が存在する。
>
>とりうる表現数の最大値を**最大表現数**と呼ぶ。

まとめると、ある大きさのニューラルネットワークの最大表現数がNのとき、訓練データ数がN個以下ならば、そのニューラルネットワークは誤差0で全ての訓練データを表現できてしまう、すなわち学習における収束先が存在することを表しています。

次に今回対象とする活性化関数であるthreshold関数について見てみます。

##threshold関数
以下で定義される関数です。

```math
\operatorname{threshold}(x) := \begin{cases}1 & (0 \leq x)\\ -1 & (o.w.)\end{cases}
```

![threshold.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602298/6948801c-1870-569b-2688-cccb5f50f471.jpeg)

実際の学習では活性化関数として使われることはほとんどありませんが、シンプルな定義であるため数学的な命題を示すのには有用な関数です。

表現数を求めるのには、「任意のデータに対して」の一文があり実験的なアプローチが難しいため、一般的には数学的なアプローチを行います。数学的アプローチには証明を伴うため、実際にはそのオーダーや値が存在する範囲を求めるのが手一杯である場合が多いですが、threshold関数の場合、その定義のシンプルさゆえに最大表現数の具体値の一般解を求めることができます。


#thresholdニューラルネットワークの最大表現数

多層パーセプトロンのニューロン数を入力側から順に$n,\,a_1,\,a_2,\,\ldots,\,a_{l-1},\,a_l,\,m$とする。(つまり入力次元がn、出力次元がm、中間層数lのニューラルネットワークです。)

このときthresholdニューラルネットワークの最大表現数は以下のようになります。

```math
\begin{cases}a_1+1 & (l = 1)\\
\min\{a_1+1,\,a_2+1\} & (l = 2)\\
\min\{a_1+1,\,2^{a_2},\,\ldots,\,2^{a_{l-1}},\,a_l+1\} & (l > 2)\end{cases}
```

この結果から、活性化関数がthreshold関数のときの最大表現数は層が増やしても大きくなることはなく、むしろ減少するのみであるため、もっとも効率的なニューラルネットワークは中間層が1層のときであるということが分かります。

まとめると、一般に**層数を増やすほどデータ表現能力が増えるとは限らない**ということです。


##なぜこのような結果になるのか
最大表現数がこのような結果になる理由として考えられるのは、各層で表現できるデータの空間が限られているということです。つまり各データは全ての層で表現できる空間を通過しなくてはいけないため、それら全ての条件を満たすことを最小値を取ることで表されていると考えられます。

今回のケースでは、中間層1層目の表現できるデータ数は$a_1+1$個であり、2層目からl-1層目の各i層目では$2^{a_i}$個、l層目は$a_l+1$個であって、訓練データがこれら全ての空間を通過するためにはデータ数が各層の容量以下、すなわちその最小値以下でなくてはならないということです。


#まとめ
活性化関数がthreshold関数のときの最大表現数についての論文内容をまとめました。
この結果から、中間層数が多いほど常に表現能力が大きくなるとは限らず、むしろ減少する場合もあることが分かりました。
Angular勉強会 #4 ライフサイクルフック


## ライフサイクルフック
Angularに限らず、多くのViewフレームワークには「ライフサイクル」という考え方がある。これはViewの生成から破棄までの状態遷移を定義したもので、あらゆるView要素を同じライフサイクルで管理することで、**効率的かつ拡張しやすい**View構造としている。

「拡張しやすさ」を生み出すために、Viewの各ライフサイクルに処理を挿入することができる。これを**ライフサイクルフック**といい、多くのViewフレームワークで標準的に備わっている機能となる。

Angularでは、Viewを管理するComponentにおいて、ライフサイクルフックが可能になっている。

---
## Angular Component のライフサイクル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447106/196a25de-25b5-cc78-0588-2f1de40808b7.png)




[Angularの公式ドキュメントも参照](https://angular.jp/guide/lifecycle-hooks#%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9)

---
## ngOnXXX を購読するには

それぞれ対応するInterfaceが用意されているので、Component内でそれを実装すればよい。
呼び出しはAngularが勝手に行ってくれる。

```ts
export class ComponentOverviewComponent implements OnInit {
  ngOnInit(): void {}
}
```

---
## ngOnDestroy は最後の砦
ngOnDestroyはコンポーネントを削除する際のファイナライザのような役割をもち、コンポーネント内で利用しているリソースの後始末を行う必要がある（それを怠るとメモリリークとなり、パフォーマンスに大きな影響を与える）

代表的なものは以下

- DOM要素へのイベントハンドラ（onClickなど）
- Promiseなどのコールバックオブジェクトの登録
- Observable要素の購読
- タイマーの停止

---
swift Chartsで折れ線グラフの作成、ｘ軸目盛りを好きな値へ変換

![Simulator Screen Shot - iPhone SE (2nd generation) - 2020-12-09 at 12.02.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/ae21b430-3270-815d-d32e-b4a724423a70.png)

これを作る

```swift.swift
import UIKit
import Charts

class ViewController: UIViewController {
    
    var chart: CombinedChartView!
    var lineDataSet: LineChartDataSet!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setData()
    }

    func setData() {
//        let yAxisValues = (1...12).map{ Double($0 * arc4random_uniform(10)) } //ランダム
        let yAxisValues:[Double] = [5.0, 0.0, 18.0, 0.0, 15.0, 54.0, 7.0, 48.0, 54.0, 70.0, 33.0, 12.0]
        
        
        let rect = CGRect(x:0, y: 30, width: self.view.frame.width, height: self.view.frame.height - 30)
        let chartView = LineChartView(frame: rect)
        var dataSets = [LineChartDataSet]()
        

        let entries = yAxisValues.enumerated().map{ ChartDataEntry(x: Double($0.offset), y: $0.element) }
        let dataSet = LineChartDataSet(entries: entries, label: "label")
        dataSets.append(dataSet)
        chartView.data = LineChartData(dataSets: dataSets as [IChartDataSet])
        
        let formatter = ChartFormatter()
        chartView.xAxis.valueFormatter = formatter
        //labelCountはChartDataEntryと同じ数だけ入れます。
        chartView.xAxis.labelCount = 12
        //granularityは1.0で固定
        chartView.xAxis.granularity = 1.0
        
        self.view.addSubview(chartView)

    }

    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    class ChartFormatter: NSObject, IAxisValueFormatter {
        let xAxisValues = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]

        func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            //granularityを１.０、labelCountを１２にしているおかげで引数のvalueは1.0, 2.0, 3.0・・・１１.０となります。
            let index = Int(value)
            return xAxisValues[index]
        }

    }
}
```

他にもさまざまなグラフを実装した
・折れ線グラフ
・棒グラフ
・横棒グラフ
・円グラフ
・点グラフ
・バブルチャート
・レーダーチャート
・ロウソク足


https://github.com/akidon0000/graphTest
Ransackでアソシエーション先のcountでソートする場合

以下のようなクラスがあったとする。

```Ruby
class Post < ApplicationRecord
  has_many :comments
end
```

```Ruby
class Comment < ApplicationRecord
  belongs_to :post
end
```

以下のような`ransacker`をPost(親側)に追記する。

```Ruby
    ransacker :comment_count do
      query = <<-SQL
        (SELECT
           COUNT(comments.post_id)
         FROM
           comments
         WHERE
           comments.post_id = posts.id
         GROUP BY
           comments.post_id)
      SQL
      Arel.sql(query)
    end
```

あとはview側で通常のソートと同じように実装する。

```ERB
<th><%= sort_link(@q, :comment_count) %></th>
```
RaspberryPiとPythonを使ってICS規格のシリアルサーボを動かす

# はじめに
近藤科学のKRSシリーズをRaspberry Piから動かそうとして四苦八苦したのでその備忘録です．


# 使ったもの
- RaspberryPi3ModelB+
- 近藤科学 KRS-6003R2HV
- ICS変換基板
- ブレッドボードや抵抗，電源，ジャンパ線などなど

### シリアル通信を行うために
今回GPIOからシリアル通信を行うのですが，Raspberry Pi3では本体のUARTがすでにBluetoothで利用されているためこれを設定し直す必要があります．今回Bluetoothを使う予定はないのでOFFにします．


### プログラム
[近藤科学の通信手順](https://kondo-robot.com/faq/ics3-5_3-6softwaremanual_2)に沿って通信します．
```(初期:EN_INをLにします) 通信する時信号が流れてないのを確認し、EN_INをHにします。 
↓
マイコンのTXからコマンドを送信します。
↓
TXからコマンドを送信終了後すぐにEN_INをLにします。 (ICS機器から信号が送られてくるのですぐ受信に切り替えます)
 ↓
マイコンのRXよりデータを受信します。
```
以下のプログラムではシリアル接続後に入力を受け付けてその値にモータを回す物になってます．

```
import serial
import sys
import time
import pigpio
def main():
    args = sys.argv
    pi = pigpio.pi()
    pi.set_mode(4,pigpio.OUTPUT)
    con = serial.Serial('/dev/ttyAMA0', baudrate=115200,bytesize=serial.EIGHTBITS,parity=serial.PARITY_EVEN,stopbits=serial.STOPBITS_ONE,timeout=1,)
    time.sleep(2)

    while 1:
        num = int(input("3500 ~ 11500 :"))

        num2 = format(num,'014b')#プレフィクス無し14桁2進数に変換，この段階でstr
        POSH = "0b" + num2[:7]#2進数のstrを分割
        POSL = "0b" + num2[7:]
        POSH = int(POSH,0)
        POSL = int(POSL,0)

        print("POSH : " + str(POSH))
        print("POSL : " + str(POSL))



        print(con.portstr)
        pi.write(4,1)#HIGH
        tx1 = 0x80
        tx2 = POSH
        tx3 = POSL
        con.write(bytes([tx1]))
        con.write(bytes([tx2]))
        con.write(bytes([tx3]))
        con.flush()
        pi.write(4,0)#low
        print(con.read())

if __name__ == '__main__':
    main()
```
## 参考サイト
https://kondo-robot.com/faq/ics3-5_3-6softwaremanual_2
【HTML5】tarckタグのdefalutがSafariだと有効にならない件

#経緯
HTML5にてvideoタグを用いて動画再生を実現することに。
今回はWebVTT使用。WebVTTについては下記の方が分かりやすいと思うので、参照してください。
[（字幕）HTML5 video および audio 用の Caption](https://qiita.com/qt6hy/items/e110dec017f03a777bf4)

で、一通り画面を作成した。

###前提
・字幕ファイルは二つ。英語と日本語を用意。
・英語の方を初回表示時の字幕として設定する(trackタグにdefalutを設定する)

###実装
~~~index.html
<video class="with-caption" controls autoplay muted>
  <!-- 動画ファイル -->
  <source src="video.mp4" type="video/mp4">
  <!-- 字幕ファイル(英語) -->
  <track label="English" kind="subtitles" srclang="en" src="sample-en.vtt" type="text/vtt" default>
  <!-- 字幕ファイル(日本語) -->
 <track label="日本語" kind="subtitles" srclang="ja" src="sample-ja.vtt" type="text/vtt">
</video>
~~~

この状態で、様々な端末で確認を行ったのだが…iPad、iPhoneのSafariだけdefalutが有効にならず、初期表示が日本語で再生される事態に。

#結論
Safariのみ、Safari設定の「優先言語」から初期の字幕を設定しているっぽい。
優先言語を変更するとその言語の字幕が初期表示される。

※Safari上でdefalutを有効化させる手段についてはまだ不明…

###補足
・テンプレート上の右下の「字幕」などの表示もブラウザの言語設定によって変化するようです。
【Rspec】ボタン（FontAwesome）が存在しないことを表現してみた

#はじめに

プログラミング歴2ヶ月の初学者です。テストコードを実装していて悩んだ部分を備忘録として記述していきます。

##環境
Rails '6.0.0'
Rspec-rails '4.0.0'

##内容

コメント機能を実装していまして、ログインしていないユーザーはコメントができない（コメントボタンが表示されない）というテストコードを記述しています。今回、コメント投稿へのリンク元をFontAwesomeを利用したボタンにしています。
これまでは、

```ruby:
expect(page).to have_no_content('新規投稿')
```

のようにhave_no_content('文字列'）を使用することで文字列が表示されていないことを確認することは理解していましたが、ボタンの非表示を確認する手段について、悩んでいました。

今回は

```ruby:
expect(page).to have_no_link('.comment-btn')
```

を使用して、実装することができました。
have_no_link('.CSSのセレクタ名')でリンク元が存在しないことを確認できました！
他に方法として、have_no_selector('.セレクタ名')などがあるみたいです！

##その他に学べたこと

後日またまとめていこうと思います。。

・「トップページへ戻る」などのa要素のリンクをクリックしたいとき

```ruby:
click_link 'トップページへ戻る（表示されている文字列）'
```

引き続き学習に励みます！！
AnimationEventレシピ ~アニメーションで当たり判定を切り替える~

まずは@sanpeitaさんの記事を見てね
https://qiita.com/sanpeita/items/a11348e47f256b8d1cf3

<h2>問題点</h2>
剣プログラムに当たり判定を追加しただけだとどんな時でも剣が敵に当たるとダメージが発生してしまう

```
 /// 剣プログラム
 private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Enemy"))
        {
            Debug.Log("<size=30>当たった!!!</size>");
        }
    }
```

<h1>この記事でできること　剣を振り下ろしたときに敵を倒すようにする</h1>

MixamoからダウンロードしたアニメーションはAnimationEventを追加できない(ReadOnly)です。Ctrl+D/command+DでMixamoのモデルに入っているAnimationClipを複製。するとAnimationEventを追加できる(編集可能)になる。
![スクリーンショット (262).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788590/26aacdf9-31be-732c-c065-92f0a75a3d82.png)



```
    /// <summary>
    /// プレイヤープログラム
    /// </summary>

   [SerializeField,Header("剣の当たり判定")] BoxCollider SwordCol;

    void Start()
    {
        SwordCol.enabled = false;
    }

    /// <summary>
    /// 剣の当たり判定をON
    /// </summary>
    void AttackStart()
    {
        Debug.Log("AttackStart呼ばれた");
        SwordCol.enabled = true;
    }

    /// <summary>
    /// 剣の当たり判定をOFF
    /// </summary>
    void AttackEnd()
    {
        Debug.Log("AttackEnd呼ばれた");
        SwordCol.enabled = false;
    }
```

剣を振り下ろしている時のみ当たり判定がでるようになった
![qitta.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788590/de415acb-6069-56db-ebc5-61ac3497dd7c.gif)
【JS】オブジェクトのプロパティを変数で指定する方法。直接指定する場合との違いについて。

オブジェクトのプロパティ名を変数で指定する場合、直接指定する方法とは異なる。

**▼変数で指定**
・`obj[変数]`


**▽直接指定**
・`obj.プロパティ名`


##変数で指定
変数でプロパティ名を指定する場合は`[ ]`で囲む。直接指定するようにドットの後に変数を記述するとundefined（そんなプロパティ存在しない）になる。

・`obj[変数]`

```js:OK
obj= {a:1, b:2 ,c:3}
str = "b"

console.log( obj[str] ) // 2
```

```js:NG
obj= {a:1, b:2 ,c:3}
str = "b"

console.log( obj.str ) // undefined 
```


<br>
###変数（配列/オブジェクト）で指定する場合

```js:OK
obj= {a:1, b:2 ,c:3}
str = ["a", "b", "c"]

console.log( obj[str[2]] ) // 3
```


<br>
##直接指定
プロパティ名を直接指定する場合はドットの後にプロパティ名を記載する。

・`obj.プロパティ名`

```js:直接指定
obj= {a:1, b:2 ,c:3}

console.log( obj.b ) // 2 
```



<br>
##実例
変数でプロパティ名を指定した場合の関数事例。

文字列を渡すと、その中に各文字が何個ずつあるかカウントして返す。


```js:
function charCount(str){
    //出力用のオブジェクト
    result = {};
    //文字を一つづつ抜き出す
    for(i = 0; i < str.length; i++){
        char = str[i].toLowerCase() //文字
        //記号やスペースは除外（a-zと0-9のみ）
        if( /[a-z0-9]/.test(char)){
        //既に値があれば+1,なければ1を代入
            if( result[char] > 0 ){
                result[char] ++;
            }
            else {
                result[char] = 1;
            };
        }
    }
    return result
}

str = "Hi There！ 1234"
charCount(str)
```

・`result[char] > 0`
resultというオブジェクトに変数charを渡して、その値が0以上か確認している。
GASとQUnitを使ってみた

# はじめに
- 例によって作業メモです。
- 参考させて頂いたブログ主様方ありがとうございます。


# 参考リンク
だいたいこの記事を読めばわかる
- [GoogleAppsScriptでユニットテスト](https://qiita.com/yooo_gooo/items/07c9513a87f6633e40c1)
- [QUnit for Google Apps Script でユニットテストを行う手順](https://oki2a24.com/2015/10/06/how-to-test-with-qunit-for-google-apps-script/)
- [Google Apps Script で Spreadsheet にアクセスする方法まとめ](https://qiita.com/negito6/items/c64a7a8589faaffcfdcf)
- [【GoogleAppsScript】スプレッドシートにHelloWorldを表示してみる](http://www.dcom-web.co.jp/technology/googleappsscript/)

# 端書
触りながら思ったことなど。

## ログの確認は別窓で
スクリプト記述ページでのログ閲覧は非常に効率が悪いため、GCPの実行ログ側で行うこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275513/3908f5c0-0657-5680-333a-be880ca29ef5.png)
スクリプトページでのログはctrl+enterでモーダルが出てくる。

Google Apps Scriptの「**実行数**」ページに実行ログが溜まっていくため、そちらを確認するのが楽。（CloudWatchと同じような使い方）
https://script.google.com/home
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275513/41c2fed6-5816-2e2f-2e8e-7d2b84fb63dc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275513/ac7e692a-0f11-49b2-4919-8a5d18928c73.png)
【Git】ディレクトリに存在する全てのファイルをリネームする

# TL;DR

```shell
find フォルダ名 -print -name "条件" | awk '$1; {gsub("変更元", "変更先", $1); print $1}' | xargs -n 2 git mv
```

## 1. find
```shell
find フォルダ名 -print -name "条件"
```
条件を満たす全てのファイルを出力してくれます

## 2. awk
```shell
awk '$1; {gsub("変更元", "変更先", $1); print $1}'
```
`mv` は `前の名前 後の名前` と指定するので、それに沿った形になるように `find` の結果を変えます。

```shell
$1;
```
`find` の結果をそのまま出力します。これが `前の名前` になります。

```shell
{gsub("変更元", "変更先", $1); print $1}
```
`find` の結果を置換してから出力します。これが `後の名前` になります。

## 3. xargs
```shell
xargs -n 2 git mv
```
`find | awk` の結果を使い、`git mv` を実行します。
XServerのドメインに Certificate Manager のドメイン認証用レコードを登録する方法

# 背景

- AWS上で新たにウェブサービスを構築することになった
- 利用するドメインは XServer で既に運用しているドメインを利用する
- CloudFront を使うので、Certificate Manager で証明書を発行する
- 自動更新したいのでドメイン認証を利用して、ドメインを設定しようとした
- ドメインを設定しようとすると `「内容」の記述に誤りがあります。` とバリデーションに失敗してレコードが登録できない


# 解決策

**内容の先頭にあるアンダースコア(_)を外して値を登録する。**

> 「 一部の DNS 実装は、CNAMEの値の部分にアンダースコアを記述することができない 」ためとのことです。ちょっと調べたところ、例えば「お名前.com」の DNS サービスではアンダースコアは TXT レコード以外で使用できないような記述がみつかりました。
> そもそも、DNS のホスト名部分ではアンダースコアを使うことは、RFC 上推奨されない状態です1。上述したサービス以外にも、アンダースコアを設定できない DNS サービスは少なくはない模様です。
> 引用元 - https://dev.classmethod.jp/articles/acm-dns-validation-without-underscore/

理由は上記の通りで、XServer のDNSサービスではアンダースコアを設定できないようになっている模様。 あと多いところだと、引用内にもあるが お名前.com の場合も同様。

実際に先頭のアンダースコアを外して登録したところ、正常に登録でき、ドメイン認証も正常にパスできた。
【Stereo Depth】Image Feature Branchで画像全体を参照

<h1>Unsupervised Learning of Stereo Matching∗</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/a17dc2d1-855c-2378-7d94-86a2d5103b98.png)


<h1>新規性</h1>
Cost Volume Branchはただ普通に右と左の画像の特徴を取り出すタダのCNN、Correlation Layerという[Dispnet](https://qiita.com/minh33/items/30fad8682887f354f2a3)で使われていた方法を使い、Pixelをwidth方向にシフトする事でCost Volumeを作る。

それだけだと画像全体の情報を失っちゃうのでImage Feature Branchというのを付け足してみたらしい。

Concatした後のネットワークはCost Volumeをrefinementする為のネットワークだと思ったのだが、あんまり詳細が書いてなかった。2018年頃からは3D CNNを使ってCost VolumeをRefinementしていくのが主流だから、あんまり細かいことを気にしないことにするm(_ _)m

<h2>Image Feature Branch</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c31cb7cb-0b5d-6417-2de2-351d4ed9af95.png)
このImage Feature Branchってのが新しく画像全体の情報を見る為に追加された

<h1>結論</h1>
・今までのCorrelation LayerによるCost Volume(単なるstereo matching)に加えてImage Featureを結合する事で画像全体を参照する事が出来るようになったはず笑。

<h1>参考文献</h1>
Unsupervised Learning of Stereo Matching
https://openaccess.thecvf.com/content_ICCV_2017/papers/Zhou_Unsupervised_Learning_of_ICCV_2017_paper.pdf