자바 로'너 는 핸드폰 으로 맞 춰 봐'라 는 작은 게임 을 만 들 었 어 요.

이 글 은 자바 기반 이 있 는 사람들 에 게 적합 하 다.

저자:DJL-Lanking
HelloGitHub 가 내 놓 은《개원 프로젝트 설명》.시리즈.다행히도 아마 존+Apache 의 엔지니어 인 Lankinghttps://github.com/lanking520을 초청 하여 DJL―완전히 자바 가 구축 한 심도 있 는 학습 플랫폼 을 설명해 주 었 습 니 다.본 고 는 시리즈 의 세 번 째 편 입 니 다.
머리말
2018 년 에 구 글 은 게이머 들 이 AI 와 직접 내 가 맞 추 는 게임 을 할 수 있 는 앱 을 출시 했다.집 하나 나 고양 이 를 그 려 내 면 AI 는 다양한 물건 이 그 려 질 확률 을 추정한다.그 실현 은 깊이 있 는 학습 모델 이 그 중에서 응용 되 었 기 때문에 깊이 있 는 신경 망 의 귀납 을 통 해 골 치 아 팠 던 회화 인식 도 손바닥 뒤 집 듯 이 쉬 워 졌 다.지금 은 간단 한 그림 분류 모델 을 사용 하면 우 리 는 회화 인식 을 쉽게 실현 할 수 있다.이 온라인 낙서 게임 을 해 보 세 요.
온라인 낙서 게임:https://djl.ai/website/demo.html
당시 대부분의 기계 학습 계산 임 무 는 여전히 네트워크 를 바탕 으로 클 라 우 드 에서 진행 되 어야 했다.계 산 력 이 계속 증가 함 에 따라 기계 학습 임 무 는 주변 설비 에 직접 배치 할 수 있 고 각종 안 드 로 이 드 시스템 을 운영 하 는 스마트 폰 을 포함한다.그러나 안 드 로 이 드 자체 가 주로 자바 를 사용 하기 때문에 파 이 썬 을 바탕 으로 하 는 각종 심도 있 는 학습 모델 을 배치 하 는 것 은 어 려 운 문제 가 되 었 다.이 문 제 를 해결 하기 위해 AWS 는 자바 맞 춤 형 딥 러 닝 프레임 워 크 인 DeepJavaLibrary(DJL)를 개발 하고 개 원 했 습 니 다.
이 글 에서 우 리 는 PyTorch 예비 훈련 모델 을 통 해 안 드 로 이 드 플랫폼 에서 낙서 회화 의 응용 을 구축 하려 고 시도 할 것 이다.총 코드 의 양 이 비교적 많 기 때문에 우 리 는 이번에 가장 중요 한 코드 를 완성 하 는 데 중점 을 둘 것 이다.너 는 후속 적 으로 우리 의 완전한 프로젝트 를 참고 하여 구축 할 수 있다.
낙서 응용 전체 코드:https://github.com/aws-samples/djl-demo/tree/master/android
환경 설정
DJL 이 필요 로 하 는 자바 기능 을 호 환 하기 위해 서 는 Android API 26 이상 버 전이 필요 합 니 다.당신 은 우리 의 사례 설정 을 참고 하여 시간 을 절약 할 수 있 습 니 다.다음은 이 프로젝트 에 필요 한 의존 항목 입 니 다.
사례 gradle:https://github.com/aws-samples/djl-demo/blob/master/android/quickdraw_recognition/build.gradle

dependencies {
 implementation 'androidx.appcompat:appcompat:1.2.0'
 implementation 'ai.djl:api:0.7.0'
 implementation 'ai.djl.android:core:0.7.0'
 runtimeOnly 'ai.djl.pytorch:pytorch-engine:0.7.0'
 runtimeOnly 'ai.djl.android:pytorch-native:0.7.0'
}
저 희 는 DJL 이 제공 하 는 API 와 PyTorch 패 키 지 를 사용 할 것 입 니 다.
3.구축 응용
3.1 첫 번 째 단계:레이아웃 만 들 기
우 리 는 먼저 View class 와 layot(아래 그림)를 만들어 안 드 로 이 드 의 전단 디 스 플레이 인터페이스 를 구축 할 수 있 습 니 다.

위의 그림 에서 보 듯 이 메 인 인터페이스 에서 두 개의View목 표를 만 들 수 있 습 니 다.PaintView는 사용자 가 그림 을 그 릴 수 있 도록 하 는 것 으로 오른쪽 아래ImageView에 서 는 추 리 를 깊이 있 게 공부 하 는 이미 지 를 보 여 주 는 데 쓰 인 다.동시에 우 리 는 화판 을 비우 기 위해 버튼 을 미리 남 겨 두 었 다.
3.2 두 번 째 단계:회화 동작 에 대응
안 드 로 이 드 장치 에 서 는 안 드 로 이 드 의 터치 이벤트 응답 을 사용자 정의 하여 사용자 의 각종 터치 조작 에 대응 할 수 있 습 니 다.우리 의 상황 에서 우 리 는 다음 세 가지 시간 응답 을 정의 해 야 한다.
  • touch Start:터치 감지 시 터치
  • touch Move:사용자 가 화면 에서 손가락 을 움 직 일 때 터치
  • touch Up:사용자 가 손가락 을 들 었 을 때 터치
  • 이와 동시에,우 리 는 사용자 가 화판 에 그린 경 로 를 paths 로 저장 합 니 다.이제 실현 코드 를 봅 시다.
    3.2.1 재 작성OnTouchEventOnDraw방법
    현재 우 리 는 다시 쓰기onTouchEvent를 통 해 각종 응답 에 대응 합 니 다.
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
     float x = event.getX();
     float y = event.getY();
    
     switch (event.getAction()) {
     case MotionEvent.ACTION_DOWN :
      touchStart(x, y);
      invalidate();
      break;
     case MotionEvent.ACTION_MOVE :
      touchMove(x, y);
      invalidate();
      break;
     case MotionEvent.ACTION_UP :
      touchUp();
      runInference();
      invalidate();
      break;
     }
    
     return true;
    }
    위 코드 에서 보 듯 이 이벤트 응답 에runInference방법 을 추가 할 수 있 습 니 다.이 방법 은 사용자 가 그림 을 그린 후에 결 과 를 추리 하 는 데 쓰 인 다.이후 의 몇 단계 에서 우 리 는 그것 의 구체 적 인 실현 을 설명 할 것 이다.
    사용자 가 그린 그림 을 다시 쓰기MotionEvent.ACTION_UP방법 이 필요 합 니 다.
    
    @Override
    protected void onDraw(Canvas canvas) {
     canvas.save();
     this.canvas.drawColor(DEFAULT_BG_COLOR);
    
     for (Path path : paths) {
     paint.setColor(DEFAULT_PAINT_COLOR);
     paint.setStrokeWidth(BRUSH_SIZE);
     this.canvas.drawPath(path, paint);
     }
     canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
     canvas.restore();
    }
    실제 그림 은 하나의onDraw에 저 장 됩 니 다.
    3.2.2 조작 시작(touch Start)
    사용자 가 터치 행 위 를 시작 할 때 아래 코드 는 새로운 경 로 를 만 들 고 경로 의 모든 점 이 화면 에 있 는 좌 표를 기록 합 니 다.
    
    private void touchStart(float x, float y) {
     path = new Path();
     paths.add(path);
     path.reset();
     path.moveTo(x, y);
     this.x = x;
     this.y = y;
    }
    3.2.3 손가락 이동(터치 이동)
    손가락 이동 중 에 우 리 는 좌표 점 을 지속 적 으로 기록 한 후에 그것들 을 quadratic bezier 로 구성 할 것 이다.일정한 오차 밸브 값 을 통 해 사용자 의 회화 동작 을 동적 으로 최적화 할 것 이다.오차 범 위 를 초과 한 동작 만 기록 된다.
    quadratic bezier 문서:https://developer.android.com/reference/android/graphics/Path
    
    private void touchMove(float x, float y) {
     if (x < 0 || x > getWidth() || y < 0 || y > getHeight()) {
     return;
     }
     float dx = Math.abs(x - this.x);
     float dy = Math.abs(y - this.y);
    
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
     path.quadTo(this.x, this.y, (x + this.x) / 2, (y + this.y) / 2);
     this.x = x;
     this.y = y;
     }
    }
    3.2.4 조작 종료(touch Up)
    터치 제어 작업 이 끝나 면 아래 코드 는 최소 사각형 목표 상 자 를 계산 하 는 경 로 를 그립 니 다.
    
    private void touchUp() {
     path.lineTo(this.x, this.y);
     maxBound.add(new Path(path));
    }
    3.3 세 번 째 단계:추리 시작
    안 드 로 이 드 장치 에서 추리 임 무 를 수행 하기 위해 서 는 다음 과 같은 몇 가지 임 무 를 완성 해 야 한다.
  • URL 에서 모델 읽 기
  • 구축 전 처리 와 후 처리 과정
  • PaintView 에서 추리 미 션 진행
  • 다음 목 표를 달성 하기 위해 서,우 리 는Bitmapclass 를 구축 하려 고 시도 합 니 다.이 단계 에서 우 리 는 이 임무 들 을 완성 하 는 관건 적 인 절 차 를 소개 할 것 이다.
    3.3.1 읽 기 모델
    DJL 안에 모델 관리 시스템 을 만 들 었 다.개발 자 는 모델 을 저장 하 는 폴 더 를 사용자 정의 할 수 있 습 니 다.
    
    File dir = getFilesDir();
    System.setProperty("DJL_CACHE_DIR", dir.getAbsolutePath());
    속성 변경DoodleModel을 통 해 모델 은 해당 경로 에 저 장 됩 니 다.
    다음 단 계 는 Criteria 가 지정 한 URL 에서 모델 을 다운로드 할 수 있 도록 정의 할 수 있 습 니 다.다운로드 한 zip 파일 에 다음 이 포함 되 어 있 습 니 다:
  • DJL_CACHE_DIR:PyTorch 모델
  • doodle_mobilenet.pt:분류 작업 의 모든 유형 을 포함 하 는 이름
  • 
    Criteria<Image, Classifications> criteria =
      Criteria.builder()
       .setTypes(Image.class, Classifications.class)
       .optModelUrls("https://djl-ai.s3.amazonaws.com/resources/demo/pytorch/doodle_mobilenet.zip")
       .optTranslator(translator)
       .build();
    return ModelZoo.loadModel(criteria);
    위 코드 는 translator 를 동시에 정의 합 니 다.그림 의 전처리 와 사후 처리 에 사 용 됩 니 다.
    마지막 으로 다음 코드 와 같이synset.txt을 만 들 고 이 를 통 해Model를 만 듭 니 다.
    
    @Override
    protected Boolean doInBackground(Void... params) {
     try {
     model = DoodleModel.loadModel();
     predictor = model.newPredictor();
     return true;
     } catch (IOException | ModelException e) {
     Log.e("DoodleDraw", null, e);
     }
     return false;
    }
    모델 로 딩 에 대한 더 많은 정 보 는 모델 로 딩 방법 을 참조 하 십시오.
    DJL 모델 로 딩 문서:http://docs.djl.ai/docs/load_model.html
    3.3.2 Translator 로 전처리 와 사후 처 리 를 정의 합 니 다.
    DJL 에서 우 리 는 Translator 인터페이스 의 전처리 와 사후 처 리 를 정의 했다.Doodle Model 에서 저 희 는 ImageClassification Translator 를 정의 하여 Translator 를 실현 합 니 다.
    
    ImageClassificationTranslator.builder()
     .addTransform(new ToTensor())
     .optFlag(Image.Flag.GRAYSCALE)
     .optApplySoftmax(true).build());
    다음은 translator 가 정의 한 전처리 와 사후 처리 가 모델 의 추리 절차 에 어떻게 사용 되 는 지 상세 하 게 논술 한다.translator 를 만 들 때 내부 프로그램 에서 분류 작업 을 할 때 모든 종류의 이름 을 자동 으로 불 러 옵 니 다.모델 의Predictor방법 이 호출 될 때 내부 프로그램 은 대응 하 는 translator 의 전처리 절 차 를 먼저 실행 한 다음 에 실제 추리 절 차 를 실행 하고 마지막 으로 translator 의 사후 처리 절 차 를 집행 한다.전처리 에 대해 서 는 이미 지 를 NDArray 로 전환 하여 모델 추리 과정의 입력 으로 사용 합 니 다.사후 처리 에 대해 서 는 추리 출력 결과(NDArray)를 softmax 로 조작 합 니 다.최종 적 으로 결 과 를 Classifications 의 인 스 턴 스 로 되 돌려 줍 니 다.
    사용자 정의 번역기 사례:http://docs.djl.ai/jupyter/pytorch/load_your_own_pytorch_bert.html
    3.3.3 PaintView 로 추리 미 션 진행
    마지막 으로,우 리 는 이전에 정 의 된 runInference 방법 을 실현 합 니 다.
    
    public void runInference() {
     //     
     Bitmap bmp = Bitmap.createBitmap(bitmap);
     //     
     bmp = Bitmap.createScaledBitmap(bmp, 64, 64, true);
     //       
     Classifications classifications = model.predict(bmp);
     //        
     Bitmap present = Bitmap.createScaledBitmap(bmp, imageView.getWidth(), imageView.getHeight(), true);
     imageView.setImageBitmap(present);
     //        
     if (messageToast != null) {
     messageToast.cancel();
     }
     messageToast = Toast.makeText(getContext(), classifications.toString(), Toast.LENGTH_SHORT);
     messageToast.show();
    }
    결 과 를 보 여 주 는 Toast 팝 업 페이지 를 만 들 것 입 니 다.예 는 다음 과 같 습 니 다.

    축하 해!우 리 는 낙서 인식 애플 릿 을 완성 했다!
    3.4 선택 가능 최적화:입력 커팅
    더 높 은 모델 추리 정확 도 를 얻 기 위해 서 는 그림 을 캡 처 하여 무의미 한 테두리 부분 을 제거 할 수 있다.

    위의 오른쪽 그림 은 왼쪽 그림 보다 더 좋 은 추리 결 과 를 얻 을 수 있다.왜냐하면 그것 이 포함 하 는 공백 테두리 가 더욱 적기 때문이다.Bound 클래스 를 통 해 그림 의 유효한 경 계 를 찾 을 수 있 습 니 다.그림 의 모든 흰색 픽 셀 점 을 덮어 쓰 는 최소 사각형 입 니 다.x 축의 가장 왼쪽 좌표,y 축의 가장 위 좌표,그리고 사각형 의 높이 와 너 비 를 얻 은 후에 이런 정보 로 우리 가 원 하 는 도형(오른쪽 그림 참조)을 캡 처 하여 코드 를 다음 과 같이 실현 할 수 있다.
    
    RectF bound = maxBound.getBound();
    int x = (int) bound.left;
    int y = (int) bound.top;
    int width = (int) Math.ceil(bound.width());
    int height = (int) Math.ceil(bound.height());
    //       
    Bitmap bmp = Bitmap.createBitmap(bitmap, x, y, width, height);
    축하 해!지금 당신 은 모든 교과 과정 내용 을 파악 하 였 습 니 다!당신 이 만 든 첫 번 째 Doodle Draw 안 드 로 이 드 게임 을 기대 합 니 다!
    마지막 으로 GitHub 에서 본 튜 토리 얼 의 전체 사례 코드 를 찾 을 수 있 습 니 다.
    낙서 응용 전체 코드:https://github.com/aws-samples/djl-demo/tree/master/android
    DJL 에 대해 서.

    딥 자바 라 이브 러 리(DJL)는 자바 기반 딥 러 닝 프레임 워 크 로,훈련 및 추 리 를 동시에 지원 한다.DJL 은 여러 가지 장점 을 얻 고 다양한 딥 러 닝 프레임 위 에 구축(TenserFlow,PyTorch,MXNet 등)하 는 동시에 여러 프레임 의 우수한 특성 을 갖 추고 있다.당신 은 DJL 을 사용 하여 훈련 을 한 후에 당신 의 모델 을 배치 할 수 있 습 니 다.
    강력 한 모델 라 이브 러 리 지원 을 동시에 가지 고 있 습 니 다.한 줄 만 있 으 면 각종 예비 훈련 모델 을 쉽게 읽 을 수 있 습 니 다.현재 DJL 의 모델 라 이브 러 리 는 GluonCV,HuggingFace,TorchHub,Keras 에서 온 모델 70 개 를 동시에 지원 합 니 다.
    프로젝트 주소:https://github.com/awslabs/djl/
    자바 로'너 는 핸드폰 으로 맞 춰 봐'를 실현 하 는 작은 게임 에 관 한 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 가 당신 의 핸드폰 으로 작은 게임 내용 을 맞 추 는 것 을 실현 합 니 다.우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 세 요.앞으로 저 희 를 많이 응원 해 주세요!

    좋은 웹페이지 즐겨찾기