- 投稿日:2020-08-06T20:39:21+09:00
Fastlane Match利用中にProvisioning ProfileをApple Developer Program上で誤って削除しちゃったら
Apple Developer Program上で複数のApp IDを管理してると、期限切れや利用不可の証明書とProvisioning Profileを一掃してくれるコマンド
fastlane match nuke
が使えなくてハマったのでメモです前提
- Fastlane Matchで証明書/Provisioning Profileを管理
- 1つのApple Developerアカウントで複数のアプリ(App ID)を管理
現象
Fastlane Matchで生成されたProvisioning ProfileをApple Developer Programで直接削除したら、
$ fastlane match developmentコマンドを実行したときに以下のエラーが出てきた
[15:50:22]: Provisioning profile 'XXXXX' is not available on the Developer Portal
[15:50:22]: for the user abc@abc.com
[15:50:22]: Make sure to use the same user and team every time you run 'match' for this
[15:50:22]: Git repository. This might be caused by deleting the provisioning profile on the Dev Portal[!] To reset the provisioning profiles of your Apple account, you can use the
fastlane match nuke
feature, more information on https://docs.fastlane.tools/actions/match/「
fastlane match nuke
を実行すれば解決するよ」とは教えてくれるが、私の環境ではnukeはできない。
なぜならば、Apple Developer Program上で複数種類のApp IDを管理している状態だと、nukeはApp ID関係なくあらゆる期限切れの証明書やProvisioning profileを削除しちゃうから使えない。(関係ないApp ID関連の物まで消しちゃう)対応
Matchfile
のgit_url("git@github.com:XXX/XXX.git)
で指定してるプライベートレポジトリ上で、Developer Program上で消してしまったProvisioning profileを直接削除すると、match
コマンドがまた使えるようになる参考URL
- 投稿日:2020-08-06T18:42:04+09:00
HtmlタグでStringを装飾する方法
- htmlタグをStringで書いて
- そのStringをData変換
- NSMutableAttributedString(data:options:documentAttributes)で装飾する
- options に documentType.html を指定
let str = "<i>testText</i>" let stringWithBaseFont = NSString(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(22)\">%@</span>" as NSString, str) stringWithBaseFont.data(using: String.Encoding.unicode.rawValue, allowLossyConversion: true)! if let attributedString = try? NSMutableAttributedString( data: stringWithBaseFont.data(using: String.Encoding.unicode.rawValue, allowLossyConversion: true)!, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) { attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: 0, length: attributedString.length)) }
- 投稿日:2020-08-06T17:39:45+09:00
Create MLで自動車部品の不良品検知
Create MLで100%検知
目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。
MLBoysで自動車部品メーカーとの技術研究を行い、
Create MLで100%の検知結果を出しました。現場で使えるのか
傷は1〜4mm程度。
(左)良品 / (右)不良品(四角い影が「圧痕」という傷)良品30、不良品30のデータでの実験となります。
現場では99%の検知能力が求められます。
製造現場では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。
そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
金属表面を分類する際のコツ
重要なのは、データセットを可能な限り一貫した画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。1、フォーカスする領域にクロップする
部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。2、撮像環境を一定にする
金属は光の反射があるので、部分による明暗が出てしまいます。
撮像環境を一定にすることで、反射のばらつきは無視できます。
カメラと部品の位置を固定して撮影します。
特別な照明は必要ありません。3、データ拡張を慎重に行う。
データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。
現場への導入に必要なこと
1、部品表面全体を画像認識する必要があります
部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。2、不良品を排除する機器に信号を送る必要があります
BlueToothなどの形で通信する必要があります。
3、過検出を防ぐ
現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
(写真)フィルターで情報量を削った金属表面結論
目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuujiCore MLやCreate ML、Visionを使ったアプリを作っています。
MLBoys:mlboys.d.yu@gmail.com
だいすけ:rockyshikoku@gmail.com
- 投稿日:2020-08-06T15:26:28+09:00
Dictionary<Key, Value>型
Dictionary<Key, Value>型
Dictionary<Key, Value>型は、
キーと値を:
で分けて、[]
で囲みます。var screenSizesInInches: Dictionary<String, Double> = ["iPhone 7": 4.7, "iPhone 7 Plus": 5.2, "iPad Pro": 12.9]var screenSizesInInches: Dictionary<String, Double> = ["キー": 値, "キー": 値, "キー": 値]スマホの、インチ(Inchi)数?
連想配列
-
Dictionary
は、連想配列らしいです。『連想配列』。 辞書(英語: dictionary)、ハッシュ(英語: hash)、マップ(英語: map)とも呼ばれる。
.
フツーの配列は、インデックス(=始点からのズレ。) で、値を特定。
連想配列では、キーによって、値を特定。まとめ休憩?
-Dictionary(=辞書)型は、キーと値がペア。
-キーをもとに、値を特定。
-キーが他のものと被るのは、NG。(値はOK)コード ?
さっき書いたコードの続き。
Keyを指定して、値をGET
import UIKit var screenSizesInInches: Dictionary<String, Double> = ["iPhone 7": 4.7, "iPhone 7 Plus": 5.2, "iPad Pro": 12.9] screenSizesInInches["iPhone 7"] // 4.7 screenSizesInInches[4.7] // No exact matches in call to subscriptという感じで、
-Keyを指定すると、値をGETできるけど、
-値を指定したら、下記のエラー。
No exact matches in call to subscript
「インデックスの呼び出しにて、マッチするもの存在しないよ」 と言われました?『キーをもとに、値を特定』するのが、Dictionaryの仕事なので、
妥当な結果だと思います。?値の削除
2パターン。
-
nil
を代入
-removeValue(forKey: "キー")
screenSizesInInches["iPhone 7"] = nil screenSizesInInches.removeValue(forKey: "iPhone 7 Plus") // どちらでも可。※waiting for key-inで、「キーの入力待ち」 的な感じで、
forKey
の for は、接続詞だと思ふ。おわりに
PlayGround、シンプルで秀逸。
参考サイト
- 投稿日:2020-08-06T14:16:01+09:00
Create MLで自動車部品の不良品検知
Create MLで100%検知
目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。
Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。
我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。
Create MLは表面異常検知の現場で使えるのか
自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。
そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
金属表面を分類する際のコツ
重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。1、フォーカスする領域にクロップする
部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。2、撮像環境を一定にする
金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。
もちろん、傷が濃く映るような明るさが理想です。ただそのために特別な証明は必要ないということです。3、データ拡張を慎重に行う。
データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。
現場への導入に必要なこと
1、部品表面全体を画像認識する必要があります
部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。2、不良品を排除する機器に信号を送る必要があります
BlueToothなどの形で通信する必要があります。
3、過検出を防ぐ
現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
(写真)フィルターで情報量を削った金属表面結論
目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuujiCore MLやCreate ML、Visionを使ったアプリを作っています。
mlboys.d.yu@gmail.com
- 投稿日:2020-08-06T12:19:56+09:00
[swift5]エラーUse of unresolved identifier 'FirebaseApp'の対処法
エラー内容
FacebookログインをFirebaseを用いて実装しようと思い、コードを書いている際に発生したエラーです。記述コードは以下の通り。
AppDelegate.swiftimport UIKit import Firebase //このコードを記述 @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. FirebaseApp.configure() //このコードを記述 return true }
FirebaseApp.configure()
の箇所にUse of unresolved identifier 'FirebaseApp'
というエラーが発生する。環境▼
swift5
Xcode 11.6原因
どうやら
pod 'Firebase/Core'
をインストールした際に、古いバージョンでインストールされていた模様。FirebaseApp
はバージョン4以上でないと定義されていないらしい。なので、
pod 'Firebase/Core'
のバージョンを更新すれば解決できそう!対処法
①対象アプリのディレクトリ内に存在する
Podfile.lock
ファイルを削除。
②ターミナルで以下のコードを実行し、podを最新状態へ更新する。(アプリのディレクトリターミナル.pod repo updateターミナル.pod update③続いて依存関係を考慮したいので、podfileには
pod 'Firebase/Core'
だけを記述して以下を実行。ターミナル.pod installこれで
最新のpod 'Firebase/Core'
と、関連のライブラリがインストールされるので、Xcodeで確認してみて下さい。エラーが解決されていると思います。なお、一度最新のpodをインストールすれば
Podfile.lock
に最新バージョンが固定される為、他のpodを入れても問題ないので安心して下さい!最後に
今回のエラーはswift初学者が高確率で遭遇するエラーだと思われます。
是非参考にして下さい!
- 投稿日:2020-08-06T11:33:28+09:00
iOS14での写真アプリへのアクセスについて
はじめに
※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。
写真アプリへのアクセスレベルの指定
iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevel
を用います。
これによりアクセスレベルを追加のみ.addOnly
、もしくは読み込み/書き込み.readWrite
に指定することができるようになりました。見た目の変化
iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。
iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、写真の追加のみ ├ 許可する └ 許可しない 読み込み/書き込み ├ 全ての写真を対象 ├ 選択した写真のみ対象 └ 許可しないといった選択肢になりました。
PHAccessLevel
を.addOnly
にしていると左画像、.readWrite
にしていると右画像のようになります。
コードでの対応
iOS13までは
PHPhotoLibrary.authorizationStatus()
に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
まとめ
iOS14からは
PHAccessLevel
の登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly
か.readWrite
を宣言する必要があります。
抜け漏れをせずに対応していきましょう。参考
- 投稿日:2020-08-06T11:33:28+09:00
iOS14での写真アプリへのアクセスレベルについて
はじめに
※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。
写真アプリへのアクセスレベルの指定
iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevel
を用います。
これによりアクセスレベルを追加のみ.addOnly
、もしくは読み込み/書き込み.readWrite
に指定することができるようになりました。見た目の変化
iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。
iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、写真の追加のみ ├ 許可する └ 許可しない 読み込み/書き込み ├ 全ての写真を対象 ├ 選択した写真のみ対象 └ 許可しないといった選択肢になりました。
PHAccessLevel
を.addOnly
にしていると左画像、.readWrite
にしていると右画像のようになります。
コードでの対応
iOS13までは
PHPhotoLibrary.authorizationStatus()
に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
まとめ
iOS14からは
PHAccessLevel
の登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly
か.readWrite
を宣言する必要があります。
抜け漏れをせずに対応していきましょう。参考
- 投稿日:2020-08-06T09:19:04+09:00
Stack Viewは便利ですね?
Stack Viewは便利ですね。
Swiftを始めて、3日目。
Stackについて学んだので、簡単にまとめ。-【Swift】超便利StackViewの実践的使い方!まだAutoLayoutで消耗してるの?
-遅ればせながら UIStackView 入門と言っても、他サイト引用です。?
-Stack
「レイアウトの修正が大変...」という
Auto Layout
の欠点を解決してくれます。
最低限のAutoLayout
の設定で済む、良心的な機能です。補足
右下に5個並んでるボタンについて、ちょっと補足。
-Stackの削除
Embed In
(一番右) にて、Unembed-Constraintの更新・削除
Resolve Auto Layout Issues
(右から2番目) にて、
Update~ が更新。
Clear~ が削除。Updateすると、上記画像のオレンジ色の「所定のConstraintからズレてるよ!」的な
警告が消える。-元のConstraintの位置に戻す
Update Frames
(一番左)
(名称が "Return Frames" じゃない理由が謎。?)※使用環境
iOS8以前では、Stack View は使用できないみたいです。
iOS9以上で利用可能。おまけ
View Controller
の召喚。
オブジェクトライブラリで、View Controllerと検索。
Is Initial View Controller
のチェックを忘れずに。
Runしたときの、EntryPoint になります。(最初に始まる画面になる。)※当たり前ですが、EntryPointの複数指定は無理なので、
他のView Controllerでのチェックは自動で消えてくれます?オブジェクトライブラリ表示。
-Command + shift + L
(Option長押し、表示を維持)
(一回ドラッグ&ドロップすれば、あとは長押し続けなくても表示を維持)終わりに。
ネイティブアプリ開発は、エミュレーターが楽しい。
PC画面上にスマホがあるという感動 ?
- 投稿日:2020-08-06T08:26:47+09:00
Create MLで不良品検知
Create MLで100%検知
目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。
Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。
我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。
Create MLは表面異常検知の現場で使えるのか
自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。
そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
金属表面を分類する際のコツ
重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。1、フォーカスする領域にクロップする
部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。2、撮像環境を一定にする
金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。3、データ拡張を慎重に行う。
データ拡張なしでCreate MLでトレーニングしたところ、Training精度は100%、Validation(検証)精度は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、100%精度を達成できました。画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。
現場への導入に必要なこと
1、部品表面全体を画像認識する必要があります
部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。2、不良品を排除する機器に信号を送る必要があります
BlueToothなどの形で通信する必要があります。
3、過検出を防ぐ
現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
(写真)フィルターで情報量を削った金属表面結論
目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuujiCore MLやCreate ML、Visionを使ったアプリを作っています。
rockyshikoku@gmail.com
- 投稿日:2020-08-06T08:26:47+09:00
Create MLで自動車部品の不良品検知
Create MLで100%検知
目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。
Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。
我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。
Create MLは表面異常検知の現場で使えるのか
自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。
そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
金属表面を分類する際のコツ
重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。1、フォーカスする領域にクロップする
部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。2、撮像環境を一定にする
金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。
もちろん、傷が濃く映るような明るさが理想です。ただそのために特別な証明は必要ないということです。3、データ拡張を慎重に行う。
データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。
現場への導入に必要なこと
1、部品表面全体を画像認識する必要があります
部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。2、不良品を排除する機器に信号を送る必要があります
BlueToothなどの形で通信する必要があります。
3、過検出を防ぐ
現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
(写真)フィルターで情報量を削った金属表面結論
目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuujiCore MLやCreate ML、Visionを使ったアプリを作っています。
mlboys.d.yu@gmail.com
- 投稿日:2020-08-06T06:21:53+09:00
iOSデバイスからAzure上の仮想ネットワークにP2S接続する
背景
iPhoneやiPadから、Azure上の仮想ネットワークにP2S接続(ポイント対サイト接続)したくなったのだが、Microsoftのドキュメントは要点が掴みづらくてわかりにくいし(機械翻訳の影響か?)、Google先生に聞いてもドンピシャな回答が見つけられなかったので、その手順を記す。
調査
そもそも、iOSデバイスでAzureにP2S接続できるのか?
公式ドキュメントには、
ポイント対サイト VPN では、次のいずれかのプロトコルを使用できます。
- SSL/TLS ベースの VPN プロトコルである OpenVPN® プロトコル。 ほとんどのファイアウォールは、TLS で使用されるアウトバウンド TCP ポート 443 を開いているため、TLS VPN ソリューションはファイアウォールを通過できます。 OpenVPN は、Android、iOS (バージョン 11.0 以上)、Windows、Linux、および Mac デバイス (OSX バージョン 10.13 以上) から接続する際に使用できます。
とあるので、
iOS 11.0以降
ならOpenVPN
が使えるのでP2S接続が可能。制限は?
上記の情報から、iOSデバイスをP2S接続するにはOpenVPNを使用することがわかった。
しかし、ゲートウェイの SKUを確認すると、最も安価な
BasicではOpenVPNが使用できない
事がわかる。
ついでにいうと、Linuxを繋ぎたい場合もOpenVPN必須なので、BasicではNG。
また、Macを繋ぎたい場合はIKEv2が必要なので、BasicではNG。
つまり、BasicでつながるのはWindowsのみ。ということで、
iOS/Mac/LinuxをP2S接続したい場合はVpnGw1以上を選択
する必要がある。説明の前提とする環境
以下のクライアント環境から、仮想ネットワーク環境に対してP2S接続する前提で記載する。
環境 アドレス範囲 仮想ネットワーク 172.16.1.0/24 クライアント (iOS) 10.0.0.0/24 クライアント環境と仮想ネットワーク環境とで、使用しているアドレス範囲に重複があると接続できないので、あらかじめどちらかのアドレス範囲を変更しておく必要がある。
また、後ほど登場するゲートウェイサブネットや、仮想ネットワークゲートウェイのアドレスプールも、これらのアドレス範囲と重複することが許されないので要注意。
手順
1. 接続先の仮想ネットワークと仮想マシンをデプロイする
これについては迷うこともないと思うので、説明は割愛する。
仮想ネットワークについては、ほとんどが
既存の仮想ネットワークに接続したい
という要件だと思うので省略することになると思う。仮想マシンは、P2S接続確立後にpingやsshなどで接続確認するときに使う。
既存の仮想マシンを流用して構わなければ省略。2. 接続先の仮想ネットワークに
アドレス空間
を追加するP2S接続を実現するには、ゲートウェイサブネットを置くためのアドレス空間が必要になる。
既存のアドレス空間に/28
の範囲を確保できるだけの余力があれば省略可能。例えば、
アドレス空間 備考 172.16.1.0/24 ← 既存のアドレス空間 172.16.2.0/24 ← 追加
のアドレス空間3.
仮想ネットワークゲートウェイ
をデプロイする
- Azure Portal上の
+リソースの作成
をクリック- 検索バーに
vpn gateway
と入力- 候補の
仮想ネットワークゲートウェイ
を選択し、作成
をクリック下記を参考に設定
設定 例 備考 名前 任意の名前を設定 地域 接続先の仮想ネットワークと同じリージョンを選択 ゲートウェイの種類 VPN SKU VpnGw1 Basic
以外を選択仮想ネットワーク 接続先の仮想ネットワークを選択 ゲートウェイ サブネットのアドレス範囲 172.16.2.0/28 '/28'の範囲が確保できていれば十分 パブリックIPアドレス VPNゲートウェイに設定されるパブリックIP。
既存の余剰IPがなければ作る。デプロイ(待ち時間に次の手順を実施しておく)
4. 証明書の生成とエクスポート
公式ドキュメントのPowerShell を使用したポイント対サイトの証明書の生成とエクスポートを参考に、別途別リージョンに構築しておいた Windows 10 の仮想マシン上で作業を行った。
手元に、 Windows 10 もしくは Windows Server 2016 の環境があれば、そこで作業して構わない。
もし、Linux上で作業をする場合はこちらの手順らしい。(未検証)実施すべき作業は、
- 自己署名ルート証明書の作成
- クライアント証明書の生成
- ルート証明書の公開キー (.cer) のエクスポート
- クライアント証明書 (.pfx) のエクスポート
5.
ユーザーVPN構成
の設定
- Azure Portalに戻って、デプロイした仮想ネットワークゲートウェイを開く
- 左側のメニューから
ユーザーVPN構成
をクリック下記を参考に設定
設定 例 備考 アドレスプール 192.168.0.0/24 他の登場人物と重複しないアドレス範囲を指定 トンネルの種類 OpenVPN (SSL) 認証の種類 Azure証明書 ルート証明書 > 名前 任意の名前を設定 ルート証明書 > 公開証明書データ 手順4−3で取得したルート証明書の公開キー文字列を貼り付け 保存
6. 構成ファイルのダウンロード
- 同画面で
VPNクライアントのダウンロード
をクリック- Zipファイルを解凍
7.
vpnconfig.ovpn
の編集
OpenVPN
フォルダ配下の、vpnconfig.ovpn
をテキストエディタで開いておく- 手順4−4でエクスポートしておいた
pfxファイル
を使用して、WindowsかLinux上で下記のコマンドを実行するopenssl pkcs12 -in "filename.pfx" -nodes -out "profileinfo.txt"
profileinfo.txt
を開き、クライアント証明書の秘密鍵文字列
と公開鍵文字列
を確認する- 以下のように、
秘密鍵文字列
と公開鍵文字列
をvpnconfig.ovpn
に上書きするvpnconfig.ovpn: 前半部分は省略 : # P2S client certificate # Please fill this field with a PEM formatted client certificate # Alternatively, configure 'cert PATH_TO_CLIENT_CERT' to use input from a PEM certificate file. <cert> -----BEGIN CERTIFICATE----- : クライアント証明書の公開鍵文字列 : -----END CERTIFICATE----- </cert> # P2S client certificate private key # Please fill this field with a PEM formatted private key of the client certificate. # Alternatively, configure 'key PATH_TO_CLIENT_KEY' to use input from a PEM key file. <key> -----BEGIN PRIVATE KEY----- : 秘密鍵の文字列 : -----END PRIVATE KEY----- </key>8. iOSデバイスに
OpenVPN Connect
アプリをインストールする9.
vpnconfig.ovpn
をiOSデバイスにインストールする
- 転送したファイルをiOSデバイスで開く
- OpenVPN Connectアプリが開いて
Import Profile
画面になるのでADD
をタップImportedProfile
画面になるので、再度ADD
をタップ10. P2S接続の確立
OpenVPN ConnectアプリのProfile画面で、トグルボタンを有効に倒す。
これでP2SのVPN接続が確立する。
VPN接続中は、画面上部の電波マーク付近にVPN
アイコンが表示される。なお、複数のVPNプロファイルがインストールされている場合で、プロファイルを切り替えたいときは、OpenVPN Connectアプリからではなく、OSの設定画面(設定>VPN)から直接プロファイルの切り替えが必要になる場合もある。
10. 動作確認
接続先の仮想ネットワーク上の仮想マシンに対して、pingやssh接続をしてみる。
iPhoneやiPadには標準のターミナルアプリが無いが、a-Shellというアプリを使うとシェルを使用できるようになる。
- 投稿日:2020-08-06T02:50:19+09:00
String.split(separator:) で Xcode Previews がコケる
SwiftUIで画面を実装中していたらXcode Previewsで表示していたプレビューが突然できなくなった。
Diagnosticsを開くとこんなエラー
Compiling failed: global function '__designTimeString(_:fallback:)' requires that 'String.Element' (aka 'Character') conform to 'ExpressibleByStringLiteral'エラーの行も表示されるので当該箇所を見たら大体こんな感じ
let str = ~ let array = str.split(separator: "\n") // ← ここでエラー発生 .map(String.init)どうやら
"\n"
(String Literal)がXcode Previews上だとCharacter
として認識されないらしい(なぜ?)解決策
Characterであることを明示すれば良い。
let array = str.split(separator: "\n" as Character) // or let array = str.split(separator: Character("\n"))参考
- 投稿日:2020-08-06T02:43:59+09:00
Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その3
勉強するコースはこれです
https://www.udemy.com/course/ios-13-app-development-bootcamp/進捗
セクション4の途中まで終了(全部で36セクション)
Xcodeの使い方など開発環境について実際の操作を学び、アプリをつくった最初はただ表示するだけのアプリ。二つ目でタップしてサイコロの目を出すアプリを開発する(ようだ)。
感想
前回の記事(Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その2)から2週間以上も間があいてしまった…
提出期限とかないしコース視聴いつでもできるし、Angela(先生)の優しさに甘えてしまった(オンラインコースあるある)
やはり絶対にこの曜日のこの時間にやるとか決まり事をつくって習慣化していかないとオンラインコースは続かないのだ(戒め)何はともあれアプリをつくって自分のiPhoneで表示させるのは実に気分が良い。
エンジニアとしてはちいさな一歩だが、初めて開発をした人にとってはおおきな一歩だとおもう。コース内の小ネタとしては、スマホアプリ黎明期に「I AM rich.という画面を表示させるだけのアプリで高額課金させて儲けるという詐欺同然の方法で稼いだ人がいた」という話が実に興味深かった。
そのアプリ持っているだけで金持ちの象徴のようなことだしアプリの内容は間違っていない(?)開発について説明中にちょくちょく小ボケがあったり興味深い話をしたり、飽きない工夫がされているので飽き性の自分でもなんとかできている気がする。
今後の予定
日曜の夜23時頃と水曜の夜23時頃に記事を書くし、書けるようにコースを進める
(習慣化できるように具体的な予定を設定する)
- 投稿日:2020-08-06T02:27:31+09:00
iOS のライブラリを自作して Carthage と CocoaPods で公開する。CI で自動化まで。
こんにちは。iOS エンジニアです。
というふうに名乗っていながら、iOS 向けのライブラリを作ったことがなかったので、やばいと思って作ってみました。
作成中の一連の流れを記事に残したいと思います。
(具体的なコードの書き方とかではないです。)成果物
https://github.com/yuki0n0/WaveSlider/
以下解説するものは、こちらのライブラリを作成したときの情報に基づいています。中身自体は大したものではないんですが、
ライブラリ公開の経験をしたかったという動機なのでお手柔らかに、、、
よかったら GitHub で Star ★ つけてね。作成
1. プロジェクト作成
Framework を選択して、次の画面で選択して、プロジェクト作る。
2. コーディング
GitHub (もしくは他の git ホスティングサービスなど) にアップしたり、中身を実装したり、自由にやってください。
サンプルプロジェクトの用意
自分のためにも、利用者のためにも、 Example プロジェクトを用意しておくといいかもしれません。
Example フォルダを作成し、その中に通常の iOS アプリの Xcode プロジェクトを作成しているパターンが多いようです。
Example ではなく Demo という名称を使用しているライブラリもありました。また、その際のライブラリ管理ファイルの書き方は、下記のようにローカルのパスを指定するように記述します。
Podfiletarget 'Example' do use_frameworks! pod "WaveSlider", :path => "../" endCartfilegit "./.."開発注意ポイント
- 公開したいクラスなどに
public
修飾子をつける- Bundle を利用する際は
Bundle.main...
ではなくBundle(for: WaveSlider.self)...
といったように書き換える。- etc...
3. 周辺ファイル
README.md
いわずもがな用意しましょう。
LICENSE
LICENSE
ファイルを用意しましょう。
CocoaPods でも紹介されている、下記サイトを参考にできます。
https://choosealicense.com/また、GitHub 上から直接
LICENSE
ファイルを作成する場合、
下記のような選択 & 編集画面が出てくるため、わかりやすいです。
Shared をチェック
Product > Scheme > Manage Schemes...
を開いて、
Shared
のチェックをつけます。
自分の確認した限りデフォルトでチェックがついていました。
その場合、一度チェックを外してから付け直すといいと思います。
公開
バージョニングの前提
セマンティックバージョニング に基づいていれば問題なさそうです。
また、Carthage はセマンティックでもalpha
rc
などの文字列が続くものはサポートされていません。つまり、バージョン名(=タグ)は下記のような通常のものだけを利用していれば問題ないと思います。
冒頭にv
などもつける必要はありません。
1.0.0
1.0.2
...1.1.0
...2.0.0
...CocoaPods
1. podspec を作成
下記コマンドで
ライブラリ名.podspec
ファイルを生成します。pod spec create ライブラリ名作成された下記のようなファイルを、書き換えていきます。
詳細なコメントが書いてあるため、そんなに困らないと思います。
困ったら公式ページを参考にしてもいいと思います。WaveSlider.podspecPod::Spec.new do |spec| spec.name = "WaveSlider" spec.version = "1.0.0" ... end下記コマンドで確認し、エラーがなくなるまで修正を繰り返し、 git push します。
pod spec lint # もし問題がなければ下記のような出力が表示されるとお見ます # [ライブラリ名] passed validation.2. Release を作成 (タグを付ける)
3. 登録作業
# 登録 # 確認メールが届くのでリンクを開いて認証する pod trunk register "メールアドレス" "名前" # CocoaPods にライブラリの登録 # 場合によっては --allow-warnings オプションを付けてもいいかもしれません pod trunk push ライブラリ名.podspecこれで終わりです!
こんな感じで作成したライブラリのページが作られていると思います!
https://cocoapods.org/pods/WaveSliderCarthage
ほぼやることはないです!
基本的に公式ドキュメントもしっかり見れるといいですね。
https://github.com/Carthage/Carthage#supporting-carthage-for-your-framework1. 確認作業
下記コマンドを実行して問題ないかを確認します。
成功した際Carthage/Build
ディレクトリに成果物ができますが、こちらは git に含める必要はないので.gitignore
に追記しておくべきです。carthage build --no-skip-current # もし成功しない場合は下記のようなコマンドを実行すると解決の糸口になるかもしれないよ by 公式ドキュメント xcodebuild -scheme SCHEME -workspace WORKSPACE build xcodebuild -scheme SCHEME -project PROJECT build2. Release を作成 (タグを付ける)
CocoaPods の方の手順と同じです。すでにやっているなら必要ないです。
---- ここまでで最低限の公開作業は終わりです! ----3. バイナリを Release にアップロードしておく (手動)
GitHub の Release には、ファイルをアップロードしておける機能があります。
画像で言う Assets の部分です。
ここにビルド済みのバイナリをアップロードしておきます。
するとライブラリ利用者側はこのバイナリを利用できるため、ビルド時間を省略できるというメリットがあります。下記コマンドを実行すると、
*.framework.zip
が作成されます。carthage build --archive
補足
アップロードされているバイナリが「Swiftのバージョンが異なる」等の理由で利用できない場合があります。
その場合は Carthage 側が自動的に判断1して、バイナリは利用せずにソースコードからビルドして利用します。
強制的にバイナリを使用したくない場合は--no-use-binaries
オプションを付与してコマンドを実行します。4. バイナリアップロードを自動化
上記の手動で行った手順を、GitHub Actions で実行します。
トリガーは release が公開されたタイミングとします。
コードは下記から御覧ください。
https://github.com/yuki0n0/WaveSlider/blob/1.0.2/.github/workflows/release_published.yamlon: release: types: [published] jobs: ...Swift Package Manager
Swift Package Manager の対応もしたいですが、時間があるときに気が向いらたらやります。
参考
- iOSライブラリの自作とcarthage公開
https://gist.github.com/sahara-ooga/18820c55cc8591694fa7aba651625908- How to get just the tag name? - GitHub Actions - GitHub Support Community
https://github.community/t/how-to-get-just-the-tag-name/16241/21- GitHub Actions で 自作Cocoapodsライブラリを自動デプロイする
https://qiita.com/ry-itto/items/0fab3fdc4321bfbd3877- What's the difference between 'pod spec lint' and 'pod lib lint'?
https://stackoverflow.com/a/32328089- Carthageの配布の仕方(すっごい簡単!)
https://qiita.com/morizotter/items/56658ed7920059beaa8e- 自作ライブラリのCocoaPods対応
https://qiita.com/am10/items/9097dd87c4eaa6ec5350- Carthgeで事前にビルドしたバイナリファイルを提供するには
https://teratail.com/questions/22246- vsouza/awesome-ios
https://github.com/vsouza/awesome-ios
Carthage 0.20.0 以降 ↩