• Overview

    • Create ML App, Create ML 프레임워크와 CreateML Components로 나뉨
    • CreateML 앱에서는 버튼 클릭으로 모델 훈련을 시킬 수 있다.
    • 앱은 프레임워크 기반이고, 모델 생성 자동화나 온디바이스 개인화 경험을 위해서는 직접 써야 한다.
    • 프레임워크는 시스템 영역의 프레임워크인 Vision, Natural Language, Sound Analysis 등의 기반이 된다.
      • 커스텀 훈련 데이터를 사용해서 모델을 커스텀할 수도 있다.
    • CreateML이 만든 모델은 시스템 영역의 프레임워크의 도움으로 앱과 함께 배포된다.
  • App enhancement

    • 커스텀 모델을 만드는 시작점은 Create ML앱이다.
    • 데이터 소스의 explore 옵션 추가
      • 특정 개체나 레이블의 어노테이션을 시각화해준다.

      • 훈련전 올바르게 어노테이션을 줬는지 미리보기를 보여준다.

      • 이미지 기반 모델(이미지 분류, 손 동작 분류 등)에서 사용 가능

        스크린샷 2024-06-21 오전 12.13.50.png

  • Object tracking

    • 공간 컴퓨팅을 위해서 디자인 된 모델

      • CreateML 카테고리에 Spatial로 추가됨
    • 3D 에셋 데이터를 훈련한다.

    • Explore object tracking for visionOS 참조

      스크린샷 2024-06-21 오전 12.21.48.png

  • Components

    • 시계열
      • 시간에 따라 변하는 수치 데이터

        • 가속센서 데이터
        • GPS 위치 정보
        • 온도 정보
      • 엄밀하게 따지면 시계열 데이터는 시간에 따라 균등하게 샘플링된 것이다.

        • 판매량 같이 연속적이지 않은 데이터도 시계열이다.
      • 시계열 분류 모델은 “이 데이터가 뭘 나타내는가”에 대한 답을 내리는 게 목적이다.

        • 기존에는 특수 케이스인 행동 분류 모델만 있었는데 이제 좀 더 강력하고 범용적인 시계열 분류 컴포넌트를 제공한다.

        스크린샷 2024-06-21 오전 12.25.45.png

      • 시계열 예측 모델을 새롭게 제공한다.

        • “다음에 뭐가 일어날 것인가?”를 답하는 게 목적이다.

        • 과거 데이터를 학습해서 미래 데이터를 예측한다.

        • 분류 모델과 마찬가지로 범용 모델로 제공

          스크린샷 2024-06-21 오전 12.28.11.png

      • 사용 예시: 푸드 트럭 판매량 예측

        • 결제시마다 데이터가 테이블 형태로 남는다.

          스크린샷 2024-06-21 오전 12.31.29.png

        • TabularData 프레임워크를 통해서 데이터를 쉽게 다룰 수 있다.

          • Explore and manipulate data in Swift with TabularData 테크톡 참조

            let grouped = dataFrame
            	.grouped(by: "Date")
            	.sums("Quantity", Int.self)
            

            스크린샷 2024-06-21 오전 12.33.54.png

        • 시계열 데이터의 일반적인 트렌드

          • 도넛 트럭 판매량은 인기가 많아서 계속 증가한다. 아이스크림도 증가하지만 도넛만큼은 아니다.
          • 아이스크림은 주말에 피크를 치는데 도넛은 꾸준히 수요가 많다.
          • 이렇듯 각 푸드트럭마다 고유한 판매 데이터를 가진다. 그래서 이에 맞게 모델을 훈련시켜야 한다.

          스크린샷 2024-06-21 오전 12.37.40.png

        • 특정 간격에서의 트렌드를 알기 위해서, 시간단위로 특징을 추출해야 한다.

          • 주중, 1년 등

          • 추출 후 전처리한 다음에 MLShapedArray로 변환한다.

            let featureExtractor = DateFeatureExtractor<Float>(features: [.month, .weekday])
            let preprocessingEstimator = ColumnSelector<_, Date>(
            	.include(columnNames: ["Date"]),
            	transformer: OptionalUnwrapper().appending(featureExtractor)
            ).appending(
            	ColumnConcatenator<Float>(
            		columnSelection: .all,
            		concatenatedColumnName: "Features"
            	)
            )
            
            let preprocessor = try await preprocessingEstimator.fitted(to: dataFrame)
            let featuresDataFrame = try await preprocessor.applied(to: dataFrame)
            
            let features = featuresDataFrame["Features", MLShapeArray<Float>.self]
            	.filled(with: MLShapedArray<Float>())
            let annotations = dataFrame["Quantity", Float.self]
            						.filled(with: 0.0)
            						.map({ MLShapedArray<Float>(scalars: [Float($0)], shape: [1]) })
            

            스크린샷 2024-06-21 오전 12.57.05.png

        • 훈련 및 검증을 위한 데이터 분리

          let trainingPortion = 0 ..< 10_000
          let training = zip(features[traningPortion], annotations[trainingPortion])
          	.map(AnnotatedFeature.init)
          	
          let validationPortion = 10_000 ..< 12_000
          let training = zip(features[validationPortion], annotations[validationPortion])
          	.map(AnnotatedFeature.init)
          
        • 며칠 단위로 예측할 것인가?

          • 일반적으로 필요한 데이터량은 예측하려는 데이터보다 많아야 한다.

          • 3일을 예측하려고 하니 15일 정도를 준비한다.

            스크린샷 2024-06-21 오전 1.00.59.png

          var configuration = LinearTimeSeriesForecasterConfiguration(
          	inputWindowSize: 15,
          	forecaseWindowSize: 3
          )
          
          let estimator = LinearTimeSeriesForecaster<Flaot>(configuration: configuration)
          let model = try await estimator.fitted(to: training, validateOn: validation)
          
          let prediction = try await model.applied(to: validation(\\.feature))