投稿

超初心者の機械学習入門

イメージ
目的  自分の撮影した写真をもとにして、スマホで画像を判別するアプリを作る --------------------- 概要 ・スマホを使った画像分類の方法を教えてくれるサイトがいくつかあるが、その多くは既存の画像データセットを用いたものである。ここでは、自分の撮影した写真を教師データとして、画像の判別アプリを作る。 ・この方法を使えば、独自の視点から画像を判別するアプリを作ることができる。例えば、家族の一人にスマホを向ければ誰であるか答えるアプリや、子どもの絵とピカソの絵を区別するアプリなどを作ることができる。 ・ここで行うのは、TensorFlow Liteの形式で機械学習モデルを作り、これを組み込んだスマホ(ここではAndroid)のアプリを作ることである。 ・TensorFlow Liteの形式でモデルを作るための比較的簡易なやりかたとして、TensorFlow  Model Maker というライブラリを使う方法があったが、2024年3月現在、これは(普通のやり方では)使えない。TensorFlow のモデルをつくるには、少なくとも初心者は別の方法を使ったほうがいい。私は書籍に従ってKerasで作成した。Model Maker の代わりにMediaPipe Model Makerを使うと良いと言われているが、私はまだこのやり方でうまくいっていない。 ・上記モデルを組み込んだアプリを作る方法を非常に親切に教えてくれるサイトがある。その通りに入力しても動かないが、わずかの手直しで画像を分類するアプリを作ることができた。  なお、この記事は約2か月前に機械学習の勉強を始めた超初心者によるものです。不備な点や誤りがあると思いますが、どうかご指摘いただければありがたいです。 ---------------------- 画像分類のモデルを作る  スマホで扱える機械学習モデルの形式として「TensorFlow Lite」がある。これを使えば、例えば花にスマホをかざすとその花の種類を5種類の中から答えてくれるといったアプリを作ることができる。  この方法を教えてくれるサイトがいくつかあるが、その多くは既存の画像のセットを使ってモデルを作るものである。しかし私は、自分の撮影した写真を教師データとして画像を分類するアプリを作りたかったので、その方法を模索した。(事情があって

KeyguardManager によるメモリリークはグーグルのバグらしい

イメージ
 KeygurardManagerによるメモリリークが確認された。どうやってこれを解消すればいいか検討したが、結論からいうと、どうやらこれはグーグルのバグで、解消できない可能性が高そうだ。(もし詳しい方がおられたら教えてください) ----------------------------  アプリを作ったら、メモリリークがないか確認しなければならない。  メモリリークとは、アプリが確保したメモリが不要になっても解放されないままになることで、使えるメモリが減ってしまい不具合の原因となる。その確認のためにリークキャナリー(LeakCanary)を入れて確認することが広く行われている。  リークキャナリーの入れ方についてはこちら。非常に簡単である。 https://zenn.dev/yass97/articles/e25960d5511c30  ただ、その読み方はちょっと難しい。今回確認されたリークは次のようなもの。  これを見ていくと、上から1/3くらいのところにKeyguardManager とあり、また、下から1/3くらいのところにAlarmActivityとある。さらにそのすぐ下にLeakinng:YES とあるので、結局、AlarmActivityというアクティビティの中にある、KeyguardManagerのインスタンスにリークがあるということなのだ。  ちなみに、KeyguardManager とは、スマホのロックを管理するクラスで、私は目覚まし時計を作る際に、スマホがロックされていてもアラームの画面だけは表示できるようにするために使ったのだ。  さて、ではどうやってこのメモリリークを解消するか。  メモリリークは多くの場合、アクティビティ等を閉じる段階(onPauseやonDestroy)において、リークの原因となっているオブジェクトを解放し、nullにしてやることで解消できる。このブログでも次のような例について、メモリリークが解消できたことを報告した。 https://marsh-mashro.blogspot.com/2023/08/broadcastreceiver.html https://marsh-mashro.blogspot.com/2023/08/handler.html  しかしKeyguardManagerのメモリリークはこのような方

ボタンの重なりとelevation

elevationで画面要素のz軸方向の高さを決めるが、そのときの発見。 ボタンが重なった時、どう反応するかということ。 結論からいくと、重なったボタンがあるとき、上(elevationの値が大きいほう)のボタンが反応するときと、そうでないときがある。 両方のボタン下のボタンのelevationを0dp、上のボタンのelevationを2dpとすれば意図どおり上が反応するが、それ以外のときはよくわからない。 なぜこういうことを考えたかというと、「画面のどこでもタップすればヘルプに飛ぶ」というようなアプリを作ろうと考えて、画面全体を覆うような透明なボタンを作った。そのうえで、一時的に画面に普通のボタンを表示して、それはまた別の機能を持つようにしようと思ったところ、後者のボタンを押すと前者の透明なボタンが反応してしまう。 そこで、elevagionを操作すればこの問題が解決できるのでは、と考え、透明なボタンを10dp、一時的な普通のボタンを20dpに設定し、これならより上にある後者のボタンが反応するだろう、と思ったのだが、うまくいかず、やっぱり前者の透明なボタンが先に反応してしまう。で、いつものように悩んでいた。 この問題は、たまたま、透明なボタンのelevationを0dp、一時的なボタンのelevationを2dpとすることで解決できた。0dpと1dpではうまくいかないときがあり、また、3dp以上でもうまくいかないことがあった。 なお、ImageViewやTextViewはこれとは関係なく、それらが上にあってsetOnClickListenerが設定されていても、下にあるボタンのほうが優先的に機能するみたいだ。 「ようだ」とか「みたいだ」が多い記事ですみません。今度時間のあるときにちゃんと検証しようと思います。

固定電話がわりのSkype

固定電話がわりに050番号を使う  固定電話を置きたいが費用やスペースや配線の手間等の点で二の足を踏んでいる場合、一つの選択肢は「スマホで使える050番号サービスを契約し、古いスマホなどSIMの入ってないスマホにそのアプリを入れて家に置いておく」というものです。  費用が安い、スペースをとらない、配線の手間は不要、などのメリットがあります。 しかし多くの050番号サービスは撤退。使えるのは(多分)Skypeのみ  ところが、2023年夏頃、なぜか、OCNが提供している050プラスを初め多くの個人向け050番号サービスが軒並み撤退してしまいました。私が把握している限り、現在この用途で使えるのはSkypeの「Skype番号」というサービスのみです。受信だけなら費用は月300円(長期契約割引あり)です(発信するためには別途前払いのクレジットを購入するか、月額プラン(現時点で867円/月、無料通話枠あり)に入る必要があります)。 Skype番号を使うには  Skype番号を使うには、運転免許などの個人を証明する書類とスマホで自撮りした顔写真をアップするなどして認証を受ける必要があります。その過程でMicrosoftのAuthenticatorを使うので、申込の前にAuthenticatorがインストールされていなければインストールし、パスワードを確認しておく必要があります。この部分は結構面倒でした。また、私だけかもしれませんが、確認ボタンがスマホの下のほう(いつもは広告が表示されるので無視する場所)に表示されるので、気づかずに確認の制限時間をオーバーしてしまうということがありました。(スマホの画面全部に注意を払いましょう) Skype番号の特徴  Skype番号には、複数のスマホにアプリを入れて都合のよいスマホで通話できるという、他の050番号サービスになかった特徴があります。なお、留守電機能はありますが、応答の音声は英語です。 使うときの工夫  電話の着信を受けるためには基本的にはSkypeアプリを立ち上げて前面に置いておかなければなりませんが、スマホの設定のところで、「アプリ→Skype→詳細設定」として(機種による違いあり)、「通知」「他のアプリの上に重ねて表示」を許可しておくと、Skypeアプリがバックグラウンドにあったり画面消灯しているときでも着信を受けることがで

SDK34におけるForegroundServiceの問題

 これまで動いていたアプリのTargetSDKを33から34に変えたところ、ForegroundServiceを立ち上げるところでいきなりエラー。その理由と対処法がわかった。  今回のバージョンアップで、ForegroundServiceには「サービスタイプ」を指定しなければならなくなった。  サービスタイプとは、そのフォアグラウンドサービスが、例えばメディア再生を行うものなのか、外部との通信を行うものなのか、といった種別のこと。次を参照。 https://developer.android.com/about/versions/14/changes/fgs-types-required?hl=ja 例えば、サービスがメディア再生を行うものであった場合は、マニフェストで、 パーミッションのところに、これまでは次の1文があれば良かった。 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 今後はそれに加えて、次の文を入れる必要がある。   <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /> さらに、<service・・・></service>の・・・の部分に  android:foregroundServiceType="mediaPlayback" を追記することも必要。 この2点を追記すると、以前と同様に動くようになった。

ビルドエラー:Attempt to create a global synthetic for 'Record desugaring' without a global-synthetics consumer の解決

このエラーで苦労している人は他にはいないでしょうか。他の原因もあるかもしれないけど、私の場合はこれで解決できたので報告します。   【問題発生の経緯】 Aというアプリを複製してBというアプリを作った(複製の方法は、以前このブログで書いた次の方法)。 https://marsh-mashro.blogspot.com/2023/08/androidstudio.html ところが、次のエラーが出てビルドができない。 Attempt to create a global synthetic for 'Record desugaring' without a global-synthetics consumer 直し方はおろか、エラーの意味すらわからず途方に暮れた。そもそも、複製前のアプリと複製後のアプリはアプリ名を除いて全く同じなのに、なぜこんなことが起きるのか・・・。 検索すると次のようなページが出てくるが、読んでもよくわからない。ただ、どうやらJavaのバージョンに関係ありそうだということがわかった。 https://www.mongodb.com/community/forums/t/how-to-properly-connect-my-kotlin-android-app-with-mongodb-atlas-cluster/196264 https://stackoverflow.com/questions/75043114/android-build-produces-error-attempt-to-create-a-global-synthetic-for-record-d そこで、build.gradleの中のJavaのバージョンを表していそうなところだとか、Project Structureだとか、今まで触ったこともないようなところを闇雲に変更したり古いバージョンを使ってみたりしたが、もちろんエラーはなくならない。 【何とか解決】 結構絶望的な気分になっていたのだが、Bのもとになった空っぽのアプリはビルドができることに気づいた。ということはGradleの問題ではない。そこで、部分的にAアプリのコピーをしてBアプリにペーストし、そのたびにビルドを試す、ということをやって

アンドロイドアプリ「相撲目覚まし」更新しました。

10月末に公開していた「相撲目覚まし」の新しいバージョンを公開しました。何とか今年中にできました。 画面を長押しすれば操作ガイドが現れたり、アラームをキャンセルしたときの音声をすぐにストップできるようにしたなど、使いやすくなったと思うので、インストールしている方はどうぞ更新してください。 https://play.google.com/store/apps/details?id=mashro.com.wixsite.mashro.dc06 です。