安卓也能机器学习,安卓机器学习入门

2,482 阅读8分钟

安卓也能机器学习,安卓机器学习入门

最近的一段时间,人工智能话题火出了天际,各个互联网大厂都在将自己的产品往人工智能的方向靠拢,似乎不跟上AI的浪潮大家就要落伍了。然而作为一名客户端开发,准确的说是一名安卓开发,似乎AI和我们较为遥远,其实不然,AI不仅仅是算法端的工作,我们安卓其实也有能搞人工智能和机器学习的,接下来听我徐徐道来。

一、什么是机器学习

机器学习是人工智能的一个分支,是使计算机具有学习能力而无需进行明确编程的科学。听起来似乎非常高大上,说人话就是让计算机像人一样通过学习数据来做出决策。这里有一个关键,如何让计算机像人一样拥有决策能力呢,这就需要计算机不断地收集新数据、调整模型、评估性能以及训练预测新数据。

二、安卓端上主流的机器学习框架有哪些

1.TensorFlow Lite:这是Google开发的一个轻量级机器学习框架,专为移动和嵌入式设备设计。它允许开发者将机器学习模型嵌入到安卓应用中。

2.ML Kit:这是Google为Firebase开发的一个机器学习套件,提供了一系列API和SDK,使得开发者可以在安卓和iOS应用中轻松使用机器学习功能。

3.PyTorch Mobile:这是Facebook开发的一个深度学习框架,提供了一系列工具和库,使得开发者可以在移动设备上运行PyTorch模型。

4.Caffe2:Caffe2是Facebook的另一款开源机器学习框架,它专为移动设备优化,可以在Android设备上运行机器学习模型。

5.MNN:MNN是阿里巴巴开源的移动端神经网络计算引擎,它提供了一套完整的神经网络计算框架,包括模型转换工具、高效轻量的推理引擎以及便捷易用的前端接口,可以帮助开发者轻松实现在移动端设备上进行神经网络模型的计算。

6.NCNN:NCNN是腾讯优图实验室开源的一个专为手机端优化的移动端神经网络计算库,NCNN目前已经应用到多款产品中,其中就有人人都在用的微信

还有非常多各类的安卓端机器学习框架,如小米的MACE、快手的KwaiNN、字节的ByteN等,可见我们安卓端还是有非常多机器学习框架供我们使用的。

三、我们安卓端在机器学习上能做什么?

安卓端在机器学习上还是有非常广的应用场景的,包括但是不限于:

1.对象识别:可以对图片或者摄像头中的物体对象检测和跟踪

2.人脸识别:获取检测到的人脸的眼睛、耳朵、脸颊、鼻子和嘴巴的坐标,作为用户id

3.文本识别:可以识别文本不同国家语言、图片文字识别等

4.语音识别和语音合成:可以用于开发语音助手,实现语音输入和语音输出,提供更自然的交互方式。

5.推荐系统:通过学习用户的行为和喜好,可以推荐用户可能感兴趣的内容。例如,在音乐、电影、购物等应用中,都可以看到推荐系统的应用。

6.行为识别:通过学习用户的行为模式,可以识别用户的活动,例如走路、跑步、骑车等。这可以用于健康和健身应用。

7.预测模型:通过机器学习,可以建立预测模型,例如预测股票价格、天气等

8.安全防护:例如,通过学习正常的系统行为,可以识别和阻止恶意行为,提高应用的安全性等等。

四、实现一个安卓端的机器学习

上面介绍了这么多机器学习相关的知识,是不是已经摩拳擦掌准备大干一场安卓机器学习开发了,什么?听起来感觉太难了?不不不,要实现一个安卓端的机器学习应用那可太简单了,因为我们有非常多的机器学习框架供我们使用,就google自身的开发的机器学习框架TensorFlow Lite和ML Kit就非常适合我们入门。

我们如果要快速实现一个安卓端机器学习应用可以选择ML Kit,因为ML Kit提供了一系列预训练的机器学习模型,以及提供了非常多常用的机器学习功能,如文本识别、面部识别、图像标签识别、条形码扫描等。ML Kit的目标是让机器学习变得更加易用和可访问,事实上也是如此,那我们话不多说,直接通过代码简单体检一下ML Kit吧。

首先第一步:我们需要将ML Kit的Android 版机器学习套件库的依赖项添加到模块的应用级 Gradle 文件。

我们这次计划实现图像标签识别的功能,所以选择图像标签识别的库

dependencies {
    //图像标签识别
    implementation 'com.google.mlkit:image-labeling:17.0.7'
}

第二步:既然我们是要实现图像标签识别,那我们就需要为ML Kit准备好图片并生成相对应的数据。

大致分为以下代码中的三步,获取图片的bitmap,获取图片的旋转角度,最后赋值给ML Kit的InputImage:

private void initImage() {
        //1.获取图片的bitmap
        Bitmap bitmap = getBitmap();
        //2.获取图片的旋转角度
        int rotate = getRotate(bitmap);
        //3.赋值给ML Kit的InputImage
        InputImage image = InputImage.fromBitmap(bitmap, rotate);
    }

获取图片的bitmap,该方法ML Kit没有提供,需要自己实现,大家也可以直接使用我们的方法

private Bitmap getBitmap(){
        Bitmap bitmap = null;
        try {
            // 获取 assets 目录下的图片
            AssetManager assetManager = getAssets();
            InputStream inputStream = assetManager.open("车.png");
            bitmap = BitmapFactory.decodeStream(inputStream);

            // 显示图片
            ImageView imageView = (ImageView) findViewById(R.id.iv_ai_image);
            imageView.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

获取图片的旋转角度,该方法ML Kit没有提供,需要自己实现,大家也可以直接使用我们的方法

private int getRotate(Bitmap bitmap){
        //接下来获取图片旋转角度
        FileOutputStream out = null;
        File file = new File(getExternalFilesDir(null), "temp.jpg");  // 创建临时文件
        try {
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  // 将Bitmap保存为.png格式的图片
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        int rotate = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(file.getAbsolutePath());
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotate = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotate = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotate = 90;
                    break;
            }
            System.out.println("Rotation: " + rotate);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return rotate;
    }

当然除了使用 Bitmap传递图片数据给ML Kit,我们还可以使用CameraX库、使用 ByteBuffer 或 ByteArray等,这里就不一一列举了。

第三步,现在我们有了图片的数据我们就可以使用ML Kit的图片标签识别了。

这里我们需要先获取一个 ImageLabeler 的实例:

ImageLabeler labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS);

然后就可以将图片信息传给process()方法:

labeler.process(image)
        .addOnSuccessListener(new OnSuccessListener<List<ImageLabel>>() {
            @Override
            public void onSuccess(List<ImageLabel> imageLabels) {
                // 识别成功
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // 识别失败
            }
        });

ML Kit处理图片信息成功后返回给我们的List imageLabels 内容格式如下:

[ImageLabel{text=Vehicle, confidence=0.9583442, index=316, mid=/m/07yv9}, ImageLabel{text=Car, confidence=0.8914178, index=423, mid=/m/0k4j}, ImageLabel{text=Bird, confidence=0.77239835, index=20, mid=/m/015p6}, ImageLabel{text=Bumper, confidence=0.7642555, index=172, mid=/m/02mnkq}, ImageLabel{text=Wheel, confidence=0.72052723, index=322, mid=/m/083wq}, ImageLabel{text=Windshield, confidence=0.533966, index=87, mid=/m/01lrnl}, ImageLabel{text=Metal, confidence=0.5333236, index=253, mid=/m/04t7l}]

其中value为“text”指的就是图片识别的标签,value为“confidence”指的就是置信水平啦(可以理解为可能性,越接1则可能性越大) 我们还可以对这些数据进行一下处理加工,让我们看得更直观,代码如下:

public void setLabelerDetector() {
        if (image == null) {
            Toast.makeText(AIActivity.this,"image为空",Toast.LENGTH_SHORT).show();
            return;
        }
        ImageLabeler labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS);
        final ImageLabel[] imageLabel = {null};
        StringBuffer stringBuffer = new StringBuffer();
        labeler.process(image).addOnSuccessListener(new OnSuccessListener<List<ImageLabel>>() {
            @Override
            public void onSuccess(List<ImageLabel> imageLabels) {
                Toast.makeText(AIActivity.this,"图片识别成功",Toast.LENGTH_SHORT).show();
                Log.d("ML_Kit", String.valueOf(imageLabels));
                int len = imageLabels.size();
                if (len > 0){
                    for (int i = 0; i < len; i++) {
                        Log.d("ML_Kit", String.valueOf(imageLabels.get(i)));
                        ImageLabel label = imageLabels.get(i);
                        if (i != 0) {
                            float last_confidence = imageLabel[0].getConfidence();
                            float next_confidence = label.getConfidence();
                            if (last_confidence < next_confidence) {
                                imageLabel[0] = label;
                            }
                        } else {
                            imageLabel[0] = label;
                        }
                        String text = label.getText();
                        float confidence = label.getConfidence();
                        stringBuffer.append("图片内容可能为"+text+",置信水平为"+confidence+"\n");
                    }
                    String result = "图片内容最有可能为" + imageLabel[0].getText();
                    stringBuffer.append(result);
                    Toast.makeText(AIActivity.this,result,Toast.LENGTH_SHORT).show();
                    mAi.setText(stringBuffer);//TextView,可以自己实现
                }else {
                    mAi.setText("未能识别到对象");//TextView,可以自己实现
                }

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(AIActivity.this,"图标标签识别失败",Toast.LENGTH_SHORT).show();
                Log.e("ML_Kit", "图标标签识别失败,e-->" + e);
            }
        });

    }

效果如下:

汽车识别.gif

我们可以看到,ML Kit为我们准确的识别出图片的标签是Vehicle——车辆,甚至我们还能来点更骚的,识别一下表情包:

表情包识别.gif

五、结语

怎么样,安卓端使用机器学习是不是很简单,如果不想用 ML Kit的预训练模型,想自己训练自己的机器学习模型还可以使用TensorFlow Lite,它允许开发者将机器学习模型转化为一种更小,更快,更高效的格式,使其可以在设备上运行,对模型有详细定制需求的开发者来说,TensorFlow Lite是一个很好的选择,篇幅有限,这里就不详细展开了,除此之外想进一步了解ML Kit的其他机器学习功能的可以到ML Kit的官网了解一下:developers.google.cn/ml-kit?hl=z…