1. 소개
Web Neural Network API는 플랫폼별 기능에 묶이지 않고 운영 체제와 기반 하드웨어 플랫폼의 기계 학습 기능을 활용하는 웹 친화적인 하드웨어 불가지론적 추상화 계층을 정의한다. 이 추상화 계층은 주요 기계 학습 JavaScript 프레임워크의 요구 사항을 다루며, ML 도메인에 익숙한 웹 개발자가 라이브러리의 도움 없이 사용자 지정 코드를 작성할 수도 있게 한다.
그림을 곁들인 소개는 해설서를 참조하라.
2. 사용 사례
2.1. 애플리케이션 사용 사례
이 절은 신경망 추론 하드웨어 가속을 위한 애플리케이션 수준의 사용 사례를 보여준다. 이러한 사용 사례의 모든 애플리케이션은 사전 훈련된 심층 신경망(DNN) [models] 위에 구축될 수 있다.
참고: 여기에 설명된 일부 사용 사례는 그 본질상 개인정보 침해적일 수 있다는 점을 유의하라. 이러한 사용 사례에 API를 사용하려는 개발자는 API가 사용자가 이해하고 승인한 목적을 위해, 사용자에게 이익이 되도록 사용되고 있음을 보장해야 한다. 개발자는 [webmachinelearning-ethics] Web Machine Learning 윤리 원칙을 적용하고, 투명성, 데이터 최소화, 사용자 제어와 같은 적절한 개인정보 위험 완화 조치를 구현해야 한다.
참고: § 3 접근성 고려 사항은 이러한 사용 사례의 접근성을 개선하는 방법에 대한 지침을 제공한다.
2.1.1. 사람 감지
사용자가 웹 기반 화상 회의 애플리케이션을 열었지만, 잠시 방을 비운다. 애플리케이션은 객체 감지(예를 들어, 단일 DNN을 사용하는 [SSD] 또는 [YOLO]와 같은 객체 감지 접근 방식)를 사용하여 사람이 포함된 카메라 입력 프레임의 영역을 감지함으로써, 그녀가 PC 앞에 있는지 감시한다.
그녀가 돌아오면, 애플리케이션은 자동으로 그녀를 감지하고 다른 온라인 사용자에게 그녀가 이제 활성 상태임을 알린다.
2.1.2. 의미론적 세그멘테이션
사용자는 사무실에 회의실이 없어 자신의 책상에서 웹 기반 화상 회의 애플리케이션을 통해 원격 회의에 참여한다. 원격 회의 중에 그녀는 자신의 방과 배경의 사람들이 보이지 않기를 원한다. 다른 사람들과 주변 환경의 개인정보를 보호하기 위해, 애플리케이션은 [DeepLabv3+], [MaskR-CNN] 또는 [SegAny]와 같은 기계 학습 모델을 실행하여 이미지를 의미론적으로 세그먼트로 나누고, 다른 사람과 배경을 나타내는 세그먼트를 다른 그림으로 대체한다.
2.1.3. 골격 감지
웹 기반 화상 회의 애플리케이션은 실시간 사람 자세 추정을 가능하게 하는 [PoseNet]과 같은 기계 학습 모델을 실행하여 사용자의 골격 자세를 추적하고, 그녀의 제스처와 몸짓 언어를 인식한다. 그녀가 손을 들면, 마이크 음소거가 자동으로 해제되고 원격 회의에서 말하기를 시작할 수 있다.
2.1.4. 얼굴 인식
회의실에 여러 사람이 있으며, 이들은 웹 기반 화상 회의 애플리케이션을 사용하여 온라인 회의에 참여한다. 애플리케이션은 객체 감지(예를 들어, [SSD]와 같은 객체 감지 접근 방식)를 사용하여 참가자의 얼굴을 감지하고, [FaceNet]과 같은 두 얼굴이 동일한지 여부를 검증하는 기계 학습 모델을 실행하여 각 얼굴이 이전 회의에 있었는지 여부를 확인한다.
2.1.5. 얼굴 랜드마크 감지
사용자는 온라인 안경 매장에서 자신에게 아름답게 어울리는 새 안경을 찾고 싶어 한다. 온라인 매장은 Face Alignment Network [FAN] 와 같은 기계 학습 모델을 실행하여 눈, 코, 입 등과 같은 얼굴 랜드마크를 감지하는 웹 기반 착용 시뮬레이터를 제공한다. 그녀가 안경을 선택하면, 시뮬레이터는 그녀의 얼굴 이미지에서 감지된 눈 위치에 선택된 안경을 적절히 렌더링한다.
2.1.6. 스타일 전이
사용자는 온라인 매장에서 화장품을 찾고 있으며 어떤 색상이 자신의 얼굴에 어울릴지 궁금해한다. 온라인 매장은 화장품의 샘플 얼굴 메이크업 이미지를 보여주고, [ContextualLoss] 또는 [PairedCycleGAN] 과 같은 기계 학습 모델을 실행하여 샘플 메이크업 이미지의 메이크업 스타일을 그녀의 얼굴 이미지로 전이하는 메이크업 시뮬레이터를 제공한다. 그녀는 시뮬레이터를 통해 선택한 메이크업이 자신의 얼굴에 어떻게 보이는지 확인할 수 있다.
2.1.7. 초해상도
웹 기반 화상 회의가 피어로부터 동영상 스트림을 수신하고 있지만, 네트워크 혼잡으로 인해 동영상의 해상도가 낮아진다. 지각되는 동영상 품질의 저하를 방지하기 위해, 애플리케이션은 [SRGAN] 과 같은 초해상도용 기계 학습 모델을 실행하여 더 높은 해상도의 동영상 프레임을 생성한다.
2.1.8. 이미지 캡션 생성
더 나은 접근성을 위해, 웹 기반 프레젠테이션 애플리케이션은 프레젠테이션 슬라이드의 설명 단어를 예측하는 [im2txt] 와 같은 기계 학습 모델을 실행하여 자동 이미지 캡션 생성을 제공한다.
2.1.9. 텍스트-이미지
이미지는 현대 웹 경험의 핵심 부분이다. 개인정보 보호 방식으로 텍스트 입력을 기반으로 이미지를 생성할 수 있는 능력은 웹 애플리케이션과 콘텐츠의 시각적 개인화와 적응을 가능하게 한다. 예를 들어, 웹 애플리케이션은 웹 페이지의 자연어 설명 또는 사용자가 텍스트 프롬프트 내에서 제공한 설명을 입력으로 사용하여 해당 텍스트 설명과 일치하는 이미지를 생성할 수 있다. 잠재 확산 모델 아키텍처 [LDM]에 의해 가능해지는 이 텍스트-이미지 사용 사례는 추가적인 텍스트-이미지 사용 사례의 기반을 형성한다. 예를 들어, 웹 페이지의 기존 이미지 일부를 새로 생성된 콘텐츠를 사용해 선택적으로 수정하는 인페인팅, 또는 그 반대인 아웃페인팅에서는 원본 이미지를 원래 크기 너머로 확장하고 빈 공간을 생성된 콘텐츠로 채운다.
2.1.10. 기계 번역
여러 나라의 여러 사람이 웹 기반 실시간 텍스트 채팅 애플리케이션을 통해 대화하고 있다. 애플리케이션은 모든 텍스트를 다른 언어로 번역하는 [GNMT] 또는 [OpenNMT]와 같은 기계 학습 모델을 사용하여 그들의 대화를 번역한다.
2.1.11. 감정 분석
사용자가 웹 기반 실시간 텍스트 채팅 애플리케이션을 통해 친구와 대화하고 있으며, 친구의 얼굴을 볼 수 없기 때문에 그 친구가 어떻게 느끼는지 궁금해한다. 애플리케이션은 입력 텍스트에서 감정을 추론하는 [DeepMoji] 와 같은 기계 학습 모델을 사용하여 친구의 감정을 분석하고, 추정된 감정을 나타내는 이모지를 표시한다.
2.1.12. 동영상 요약
웹 기반 화상 회의 애플리케이션은 수신된 동영상 스트림을 녹화하며, 저장할 녹화 동영상 데이터를 줄여야 한다. 애플리케이션은 [Video-Summarization-with-LSTM]과 같은 동영상 요약용 기계 학습 모델을 사용하여 녹화된 동영상의 짧은 버전을 생성한다.
2.1.13. 잡음 억제
웹 기반 화상 회의 애플리케이션은 수신된 오디오 스트림을 녹음하지만, 일반적으로 배경 잡음은 어디에나 있다. 애플리케이션은 화상 회의의 오디오 경험을 개선하기 위해, 아기 울음소리나 개 짖는 소리와 같은 배경 동적 잡음을 억제하는 데 [RNNoise]와 같은 순환 신경망을 사용하는 실시간 잡음 억제를 활용한다.
2.1.14. 음성 인식
speech to text라고도 알려진 음성 인식은 말해진 언어를 텍스트로 인식하고 변환할 수 있게 한다. 음성 인식의 예시 애플리케이션에는 전사, 자동 번역, 멀티모달 상호작용, 실시간 캡션 및 가상 비서가 포함된다. 음성 인식은 청각 콘텐츠의 접근성을 개선하고, 개인정보 보호 방식으로 이러한 콘텐츠와 텍스트 형식으로 상호작용할 수 있게 한다. 일반적인 사용 사례의 예로는 동영상 시청 또는 실시간 캡션을 사용한 온라인 회의 참여가 있다. [Whisper]와 같은 모델은 정확도와 견고성에서 인간에 가까워지고 있으며, 이러한 사용 사례의 접근성을 개선하기에 적합하다.
2.1.15. 텍스트 생성
다양한 텍스트 생성 사용 사례는 텍스트 시퀀스에서 다음 항목을 예측하는 일반적인 능력이 필요한 작업을 수행할 수 있는 대규모 언어 모델(LLM)에 의해 가능해진다. 이 모델 클래스는 텍스트를 번역하고, 텍스트 입력을 기반으로 질문에 답하고, 더 큰 본문을 요약하거나, 텍스트 입력을 기반으로 텍스트 출력을 생성할 수 있다. LLM은 RNN, CNN 또는 LSTM 아키텍처를 기반으로 한 이전 모델에 비해 더 나은 성능을 가능하게 하며, 이 절에서 논의된 많은 다른 사용 사례의 성능을 더욱 향상시킨다. LLM의 예에는 [t5-small], [m2m100_418M], [gpt2], 그리고 [llama-2-7b]가 포함된다.
2.1.16. 가짜 동영상 감지
사용자는 웹에서 ‘deepfake’로 생성된 사실적인 가짜 동영상에 노출된다. 가짜 동영상은 사용자를 정치적으로 선동하거나 사용자의 의견을 조작하기 위해 화자의 얼굴을 대통령의 얼굴로 바꿀 수 있다. [FaceForensics++]와 같은 deepfake 감지 애플리케이션은 동영상을 분석하고 사용자를 가짜 동영상이나 이미지로부터 보호한다. 사용자가 웹에서 가짜 동영상을 시청할 때, 감지 애플리케이션은 실시간으로 해당 사기 동영상을 사용자에게 경고한다.
2.2. 프레임워크 사용 사례
이 절은 신경망 추론 하드웨어 가속을 위한 전용 저수준 API에 대한 프레임워크 수준의 사용 사례를 모은다. 기계 학습 프레임워크가 Web Neural Network API(WebNN API)의 주요 소비자가 될 것으로 예상되며, WebNN API를 통해 노출되는 저수준 세부 사항은 일반적인 웹 개발자로부터 추상화된다. 그러나 기계 학습에 특정한 관심과 역량을 가진 웹 개발자는 더 높은 수준의 ML 프레임워크 대신 WebNN API와 직접 인터페이스하기를 원할 것으로도 예상된다.
2.2.1. 사용자 지정 계층
웹 애플리케이션 개발자는 WebNN API에서 DNN 모델을 실행하고 싶어 한다. 그러나 그녀는 [LeakyReLU], [ELU] 등과 같은 일부 활성화 함수가 WebNN API에 포함되어 있지 않다는 것을 발견했다. 이 문제를 해결하기 위해, 그녀는 추가 활성화 함수를 WebNN API 위에 사용자 지정 계층으로 구성한다. 사용자 지정 계층의 범위에는 활성화뿐만 아니라 컨볼루션, 정규화 등도 포함될 수 있음을 유의하라.
2.2.2. 네트워크 연결
웹 애플리케이션은 DNN 모델을 사용하며, 그 모델 데이터 중 상위 컨볼루션 계층과 하위 완전 연결 계층은 별도의 파일에 저장된다. 이는 완전 연결 계층의 모델 데이터가 서버 측의 미세 조정으로 인해 주기적으로 갱신되기 때문이다.
따라서 애플리케이션은 처음에 두 부분 모델 파일을 모두 다운로드하고 이를 단일 모델로 연결한다. 모델이 갱신되면, 애플리케이션은 모델의 미세 조정된 부분을 다운로드하고 완전 연결 계층만 그것으로 대체한다.
2.2.3. 성능 적응
웹 애플리케이션 개발자는 모바일 기기에서 자신의 DNN 모델의 성능에 대해 우려하고 있다. 그녀는 GPU 가속이 없는 모바일 기기에서는 모델이 너무 느리게 실행될 수 있음을 확인했다. 이 문제를 해결하기 위해, 그녀의 웹 애플리케이션은 WebNN API를 참조하여 가속이 사용 가능한지 여부를 확인하고, 가속이 없는 기기에 경고를 표시할 수 있게 한다.
몇 주 후, 그녀는 CPU에서도 실행될 수 있는 작은 DNN 모델을 개발했다. CPU 실행을 수용하기 위해, 그녀는 CPU 전용 기기의 경우 애플리케이션이 작은 모델을 로드하도록 애플리케이션을 수정한다.
2.2.4. 연산 수준 실행
JavaScript ML 프레임워크는 ML 모델을 로드하고, 해석하고, 실행하는 일을 담당한다. 모델 실행 단계에서, 프레임워크는 모델의 연산을 반복하고 각 연산을 CPU, GPU 또는 ML 가속기와 같은 하드웨어 기기에서 실행한다. 기기 간 불필요한 데이터 복사를 피하기 위해, 프레임워크는 연산을 실행할 동일한 기기를 선택한다. 컨볼루션 2D 또는 행렬 곱셈과 같은 계산 집약적 연산의 경우, 프레임워크는 선택된 기기에서 사용할 수 있는 ML 특화 가속으로 이를 실행하기 위해 WebNN API를 사용한다.
2.2.5. 실시간 동영상 처리와의 통합
WebRTC 기반 화상 회의의 사용자 경험은 실시간 동영상 처리를 사용하여 향상된다. 예를 들어, § 2.1.2 의미론적 세그멘테이션 모델을 사용하여 구현된 배경 흐림은 사용자의 실시간 카메라 피드에서 배경을 흐리게 한다. 이 사용 사례의 성능 요구 사항을 충족하기 위해, WebNN API는 WebNN API 기반 실시간 동영상 스트림 변환을 허용하도록 미디어 파이프라인을 구성하는 다른 Web API의 프리미티브와 통합된다.
3. 접근성 고려 사항
이 절은 신경망 추론 하드웨어 가속으로 가능해지는 § 2.1 애플리케이션 사용 사례의 접근성을 개선하는 방법에 대해 웹 작성자에게 지침을 제공한다. 이 지침은 이 명세에 개요로 제시된 특정 사용 사례를 넘어 일반화되며, 웹 작성자는 추가 접근성 지침을 위해 [wcag]를, 윤리적 원칙의 맥락에서 디지털 접근성을 위해 § 6 윤리적 고려 사항을 참조할 것이 권장된다.
§ 2.1.8 이미지 캡션 생성은 캡션이 스크린 리더 및 기타 보조 기술(AT) 사용자에게 제공되도록 보장함으로써 개선될 수 있다. 웹 작성자는 생성된 이미지 캡션이 각각의 이미지와 의미론적으로 연결되도록 보장할 것이 권장된다. 표준 alt 속성을 통해 연결하거나, 설명이 초기 페이지 로드 시 갱신되는지 또는 나중에 사용자 동작의 결과로 갱신되는지에 따라 달라질 수 있는 다른 방법을 사용할 수 있다.
§ 2.1.11 감정 분석은 사용자를 잘못 레이블링하고 따라서 잘못 분류하여 차별적인 경험으로 이어질 수 있다. 웹 작성자는 신뢰도 점수를 노출하고 사용자에게 해당 기능을 끌 수 있는 선택권을 제공할 것이 권장된다.
§ 2.1.13 잡음 억제는 공격적인 필터를 사용할 경우 구음 장애가 있는 사용자의 말을 제거하여 캡션과 인식이 실패하게 만들 수 있다. 웹 작성자는 우회 또는 민감도 제어를 노출하고, 실시간 캡션이 활성화된 경우 잡음 억제를 고정하지 않을 것이 권장된다.
§ 2.2.5 실시간 동영상 처리와의 통합에서 배경 흐림 기반 세그멘테이션은 방해 요소를 제거하는 데 도움이 되지만, 입술 읽기와 실시간 캡션을 방해할 만큼 지연을 너무 많이 추가할 수 있다. 웹 작성자는 사용자-facing 키보드 및 스크린 리더로 조작 가능한 “배경 흐림 켜기/끄기” 제어를 다른 접근성/미디어 설정 옆에 표시할 수 있는 기능을 제공할 것이 권장된다.
§ 7.2 장치 선택은 웹 작성자가 실행 속도와 전력 소비에 대한 선호를 나타낼 수 있게 한다. 구현자는 저사양 또는 배터리에 민감한 기기의 사람들이 특히 휴대용 AAC 또는 시선 추적 설정에서 캡션 및 기타 중요한 접근성 기능을 계속 반응성 있게 유지할 수 있도록, 브라우저 UI에서 사용자가 웹 작성자의 힌트를 재정의할 수 있게 할 것이 권장된다.
4. 보안 고려 사항
이 명세는 신경망 추론 하드웨어 가속을 위한 저수준 API를 정의한다. 이 API는 사용자의 컴퓨터에 대한 저수준 접근을 부여하기 때문에 강력한 기능 [POWERFUL-FEATURES]으로 간주된다. 강력한 기능의 인증 및 기밀성 기대 사항을 충족하고 중간자 공격을 방지하기 위해, 이 명세에서 정의하는 모든 인터페이스는 보안 컨텍스트에서만 사용할 수 있다.이 API는 § 7.5 Permissions Policy 통합을 사용하여 모든 교차 출처 프레임에서 기본적으로 비활성화된다. 이는 임베딩 페이지가 권한을 부여하는 정책을 명시적으로 설정하지 않는 한 서드파티 콘텐츠가 이 API를 사용하는 것을 방지한다.
이 API는 WebGPU 명세에서 정의한 GPUDevice로부터
MLContext를 생성할
수 있게 한다.
이 컨텍스트의 보안 특성에 대한 자세한 내용은 WebGPU 보안 고려
사항을 참조하라.
이 API는 GPU, CPU 및 전용 ML 가속기 하드웨어 전반에 대한 추상화를 제공한다. GPU를 사용할 때는 WebGPU와 유사한 서비스 거부 고려 사항이 적용된다. CPU 또는 전용 ML 가속기를 사용할 때는 잠재적 리소스 경합의 유형이 다르며, 완화 조치는 구현 및 구성에 따라 달라진다. 구현은 사이트가 시스템 리소스를 불공정하게 많이 사용하는 것을 방지하기 위해 플랫폼에서 사용할 수 있는 어떤 메커니즘이든 사용해야 한다. 이러한 계산 유닛은 공유 리소스이며, 어떤 계산 API의 사용도 부하가 가득 찬 시스템의 전체 성능에 영향을 미친다.
그래프가 완전히 구성되고 컴파일되면, 그래프 내 각 연산으로 들어가는 입력 형태가 추론되고 확정된다. 실제 데이터에 대해 그래프를 실행하는 compute 메서드가 호출될 때 경계 검사가 발생한다. 이 단계 이전에는 실제 데이터가 컴파일된 그래프에 바인딩되지 않는다. 그 시점까지 이미 추론된 데이터의 형태에 대해 적절한 경계 검사가 이루어지도록 보장하는 것은 구현의 책임이다.
구현자에 대한 지침으로 범위 밖 접근에 취약한 연산을 문서화한다.
구현은 상수로 간주되는 데이터의 변경에 기반한 제어 흐름 공격을 방어해야 한다. 예를 들어, 기반 플랫폼의 최적화는 계산 전체에서 가중치가 변경되지 않는다고 가정할 수 있다. API가 계산 중에 가중치를 보관하는 버퍼의 내용을 변경할 수 있게 한다면, 이러한 최적화 가정은 무효화되어 기반 플랫폼에서 정의되지 않은 동작을 일으킬 수 있다. API는 항상 버퍼를 복사하거나 전송함으로써 스크립트로부터 발생하는 이 공격 범주를 완화하지만, 구현은 상수로 간주되는 데이터의 프로세스 격리와 같은 추가 방어를 고려해야 한다.
미래 대비 조치로, API 설계는 일반적으로 에뮬레이션될 수 있는 특정 연산이 보안, 성능 또는 기타 이유로 호환성을 깨뜨리지 않고 폐기될 수 있게 한다. 이는 이 명세에서 정의된 더 작은 프리미티브 연산으로 정의되는 고수준 함수에 의해 가능해진다. 이를 통해 고수준 함수의 네이티브 구현을 폴리필 구현으로 대체할 수 있다.
CPU가 렌더러를 실행하는 프로세스 간에 공유되는 현재 상태를 고려하여 사이드 채널 공격의 실현 가능성을 조사한다.
공격자가 결함을 포함할 수 있는 특정 구현을 표적으로 삼지 못하게 하기 위해, § 7.2 장치 선택 메커니즘은 힌트일 뿐이며, 구체적인 장치 선택은 구현에 맡겨진다. 예를 들어 사용자 에이전트는 알려진 취약점이 있는 장치에서 모델을 절대 실행하지 않도록 선택할 수 있다. 추가 완화 조치로, 장치 열거 메커니즘은 정의되지 않는다.
힌트 제공은 이 우려를 부분적으로 완화한다. 추가 완화 조치를 조사한다.
API 설계는 컴파일된 계산 그래프의 공격 표면을 최소화한다. 다양한 연산을 호스트하는 MLGraphBuilder
인터페이스는 데이터 정의 API이며, 따라서 아무것도 실행하지 않고 데이터만 구성한다.
그 결과 공격 가능성은 MLContext.dispatch()
메서드를 호출하여 실행하기 전에 데이터를 그래프에 바인딩할 때로 제한된다. 이를 통해 구현자는
MLContext.dispatch()
메서드를 강화하는 데 집중할 수 있다. 예를 들어, 데이터의 경계를 준수하고 경계가 지켜지지 않을 때
적절히 실패하도록 보장할 수 있다.
고해상도 시간을 측정하기 위한 목적 특화 Web API는 해상도 감소, 지터 추가, 남용 감지 및 API 호출 제한과 같은 기법을 사용하여 타이밍 공격을 완화한다 [hr-time-3]. WebNN 구현의 실제 배포는 타이밍 공격을 비현실적으로 만들기에 충분한 지터를 가져올 가능성이 높지만 (예: IPC를 사용하기 때문), 구현자는 자신의 구현을 타이밍 공격에 대해 고려하고 테스트할 것이 권고된다.
참고: Unicode 시퀀스와 관련된 보안 위험은
label
USVString
정의의 맥락에서 논의된다.
4.1. 새 연산에 대한 지침
이 절은 비규범적이다.
이 명세에서 정의되는 연산이 안전하게 구현될 수 있는 방식으로 형성되도록 보장하기 위해, 이 절은 구현 문제의 가능성을 줄이도록 연산이 어떻게 정의될 것으로 예상되는지에 대한 지침을 포함한다. 이러한 지침은 업계 모범 사례와 맞추기 위해 시간이 지남에 따라 진화할 것으로 예상된다.
-
인수의 단순성을 선호한다
-
복잡한 데이터 형식에 파서를 사용하지 않는다
-
연산이 저수준 프리미티브로 분해될 수 있다면:
-
정보 제공용 에뮬레이션 경로를 추가한다
-
새로운 고수준 연산보다 프리미티브를 선호하되 성능 결과를 고려한다
-
-
연산 입력과 속성에 대해 일관된 스타일을 따른다
-
풀링 및 축소와 같은 연산 계열에 대해 API 형태와 옵션을 공유한다
-
가능할 때마다 실패 사례를 테스트 사례로 형식화한다
-
의심스러우면 제외한다. 사용 사례를 만족시키는 데 가능한 한 작은 API 표면을 유지하되, 그보다 작게 만들지는 않는다
-
미래의 진화를 방해할 수 있는 구현 세부 사항이 API에 포함되지 않도록 노력하고, 과도하게 명세하지 않는다
-
빠르게 실패한다. 웹 개발자가 문제를 더 빨리 알수록 더 좋다
일반적으로 새 기능을 추가할 때는 Technical Architecture Group과 Privacy Interest Group이 [security-privacy-questionnaire]에 문서화한 보안 및 개인정보 보호 영향을 항상 고려한다.
5. 개인정보 보호 고려 사항
이 API는 민감한 사용자 데이터를 브라우저의 샌드박스 내에 유지함으로써 클라우드 기반 추론 대안에 비해 개인정보 보호 개선을 제공한다. 이미지, 오디오, 동영상 스트림 및 기타 개인정보와 같은 입력 데이터는 사용자의 장치를 떠나지 않으므로, 원격 서버로의 데이터 전송 및 서드파티 데이터 처리와 관련된 위험을 제거한다.
그러나 하드웨어 가속 기능과 밀접하게 상호작용하는 강력한 로컬 계산 API로서, WebNN API는 성능 최적화와 개인정보 보호 사이의 균형을 맞춰야 한다. 이 API는 효과적인 기계 학습 추론 기능을 가능하게 하면서도 핑거프린팅을 완화하기 위한 여러 개인정보 보호 조치를 포함한다.
5.1. 핑거프린팅
설계상, 이 API는 식별된 § 2 사용 사례를 최상의 성능과 결과의 신뢰성으로 다루기 위해 필요한 최소한의 정보만 노출하는 것을 목표로 한다. 첫째, API는 표준화를 통해 핑거프린팅을 완화한다. 즉, 다양한 플랫폼 API 전반에서 일관된 동작을 정의하고, 적합한 구현 전반에서 기반 하드웨어 변동에 관한 정보 누출을 최소화한다. 이는 다음을 통해 달성된다.
-
하드웨어에 구애받지 않고 데이터 최소화 원칙에 따라 기반 플랫폼의 저수준 세부 사항 노출을 최소화하는 § 7.3 오퍼레이터.
-
웹 개발자가 실행 속도와 전력 소비에 대한 선호를 나타낼 수 있게 하지만, 실행을 위해 실제로 선택된 장치를 노출하지 않고, 웹 개발자가 특정 장치를 열거하거나 선택할 수 있게 하지 않는 § 8.2.1 MLContextOptions API. 이 힌트 메커니즘은 엔트로피를 추가하지 않는다.
-
웹 개발자가 사이드 채널을 사용하여 이 정보를 추론하는 대신 명시적인 쿼리 API를 사용하여 특정 오퍼레이터에 대한 지원을 질의할 수 있게 하는 § 8.3.7 opSupportLimits() API. 이 API는 핑거프린팅 가능성에 기여할 수 있지만, 적절하게 버킷을 사용하여 이 API를 통해 노출되는 구별 가능한 구성의 수를 제한함으로써 그 엔트로피를 줄일 수 있다.
-
서로 다른 백엔드 구현 전반에서 일관된 오류 처리.
전체 설계는 구현이 서로 다른 플랫폼 전반에서 일관된 인터페이스를 유지하면서 필요한 기능을 제공하도록 보장한다. 플랫폼별 세부 사항을 추상화함으로써, API는 기반 가속이 CPU, GPU 또는 전용 ML 하드웨어에 의해 제공되는지 여부와 관계없이 개인정보 보호를 유지하는 예측 가능한 동작을 제공할 수 있다.
참고: MLContextOptions
는 활발히 개발 중이며, 더 많은 구현 경험과 더 넓은 웹 커뮤니티의 새로운 사용 사례를 바탕으로
설계가 변경될 것으로 예상된다.
MLGraph.devices API 확장이 그래프가 완전히 구성되고 컴파일된 후 실행을 위해 실제로
선택된 장치를 노출하도록 제안되었다. 이 API 확장의 개인정보 보호 영향은 조사 중이다.
[Issue #836]
5.2. 실행 시간 분석
연산의 타이밍 특성은 기반 하드웨어 성능에 대한 일부 간접 정보를 제공할 수 있으며, 이는 모든 계산 API에 내재된 특징이다. 특정 상황에서 실행 시간 분석은 한 기반 플랫폼의 신경망 하드웨어 가속 기능 성능을 다른 기반 플랫폼에 비해 간접적으로 드러낼 수 있다. 타이밍 공격에 대한 추가 논의는 § 4 보안 고려 사항도 참조하라.
참고: 그룹은 제안된 실행 시간 분석 핑거프린팅 벡터와 완화 조치에 대한 추가 의견을 환영한다.
5.3. WebGPU 비교
WebGPU와 달리, 이 API는 본질적으로 사용자 지정 셰이더 작성을 지원하지 않는다. 따라서
셰이더 캐시 또는 기타 지속적 데이터에 의존하는 타이밍 공격에 취약하지 않다.
이 API는 브라우저 또는 기반 OS의 기존 셰이더와 저수준 프리미티브 위에 구축된다.
GPUDevice
와 인터페이스하는 웹 개발자는 WebGPU
컴파일 캐시 고려 사항을 알고 있을 것으로 기대된다.
WebGPU API는 기계별 아티팩트를 개인정보 보호 고려 사항으로 식별한다. 마찬가지로, WebNN API의 계산 유닛 스케줄링은 특정 상황에서 핑거프린트를 도입할 수 있다. 그러나 WebGPU와 유사하게, 이러한 핑거프린트는 각 벤더의 대부분 또는 모든 장치에서 동일하므로 우려를 완화한다. 또한 소프트웨어 구현을 사용하여 이러한 아티팩트를 추가로 제거할 수 있다.
일반적으로 이 API의 구현자는 해당되는 경우 자신의 구현에 WebGPU 개인정보 보호 고려 사항을 적용할 것으로 기대된다.
6. 윤리적 고려 사항
워킹 그룹은 규범적 명세가 어떤 완화 조치를 고려해야 하는지 식별하는 데 도움을 주기 위해, 웹에서 기계 학습을 사용하는 것과 관련된 윤리적 문제를 문서화하기 시작했다. 워킹 그룹은 더 넓은 커뮤니티가 전용 GitHub 저장소를 통해 기여할 수 있는 Web Machine Learning 윤리 원칙 문서 [webmachinelearning-ethics]를 공개하고 유지한다.
7. 프로그래밍 모델
7.1. 개요
신경망의 핵심에는 수학적 연산의 계산 그래프가 있다. 이러한 연산은 컴퓨터 비전, 자연어 처리 및 로보틱스에서 현대 기계 학습 기술의 구성 요소이다. WebNN API는 신경망의 계산 그래프를 구성, 컴파일 및 실행하기 위한 명세이다.
MLGraph
인터페이스는 불변인 컴파일된 계산 그래프(즉, 모델)를 나타낸다.
MLGraphBuilder
인터페이스는 계산 그래프(그
그래프)를
구성하는 빌더(factory) 역할을 하며,
이후 컴파일되어 MLGraph를
생성한다.
WebNN에서 계산 그래프는
데이터에 작용하며 그래프의 노드인
오퍼레이터로 구성된다. MLOperand들은
계산 그래프 내에서 흐르는 데이터의 표현이며, 그래프의 간선이다. MLOperand들은
추론을 위한 계산 그래프의
입력 값, 추론에 사용되는
상수(훈련된 가중치 포함),
추론 중에 계산되는 중간 값(흔히 활성화라고 함), 그리고 추론의 출력 값을 포함한다.
오퍼레이터의
입력은 하나 이상의 MLOperand이다.
오퍼레이터의 출력은 하나 이상의
MLOperand이다.
오퍼레이터는 그 동작을 제어하는
오퍼레이터별 매개변수를 가지며, 여기에는 0개 이상의 활성화 함수가 포함될 수 있다.
MLGraphBuilder
인터페이스의 핵심 부분은 gemm()
및 relu()
와 같은 메서드이다. 이 메서드들은 계산이 실행될 때 입력 데이터에 수행할 실제 연산을 나타내는
오퍼레이터를 생성하고,
해당 오퍼레이터를 보유하는 새 MLOperand를
반환한다. MLOperand를
생성하는 메서드는 모든 입력과
활성화를
오퍼레이터에 연결한다. 각 메서드 호출은 다른 어떤 MLOperand의
값도 변경하지 않고, 구별되는 새 값을 반환한다.
오퍼레이터는
레이블을 가지며, 이는 예외 메시지와 같은 진단에 포함될 수
있는 문자열이다.
오퍼레이터가 생성될 때 그
레이블은 구현
정의 방식으로 초기화되며, 전달된 label을
포함할 수 있다.
dispatch()
중 오류를 보고하기 위한 메커니즘 추가를 고려한다.
[Issue #778]
추론 시, 모든 MLOperand는
본질적으로 다차원 배열인 텐서(실제 데이터)에 바인딩된다. 텐서의 표현은
구현에 따라 다르지만, 일반적으로 어떤 버퍼(메모리)에 저장된 배열 데이터와
배열 데이터(예: 그 형태)를 설명하는 일부 메타데이터를 포함한다.
계산 그래프 내 연산은 함수적 의미론을 가진다. 이를 통해 구현은 여러 텐서 간에 배열 데이터를 잠재적으로 공유할 수 있다. 예를 들어, reshape 또는 slice와 같은 연산의 구현은 입력 텐서와 동일한 버퍼를 공유하는 입력 텐서의 뷰를 반환할 수 있다. (reshape의 경우 전체 데이터가 공유되는 반면, slice의 경우 입력 데이터의 일부가 공유된다.) 구현은 위와 같은 뷰를 중간 값에 사용할 수 있다.
실행 전에, 하나 이상의 지정된 출력을 계산하는 데 사용되는 계산 그래프는 변환, 컴파일 및 최적화되어야 한다. 컴파일 단계의 핵심 목적은 연산 또는 루프 융합과 같이 둘 이상의 연산에 걸친 최적화를 가능하게 하는 것이다. 사용자 에이전트는 그래프 변환 중에도 이러한 최적화를 수행할 수 있다.
MLGraphBuilder.build()
메서드는 호출 스레드를 차단하지 않고 백그라운드에서 그래프를 컴파일하며, Promise를
반환한다. 이 Promise는 MLGraph로 resolve된다.
각 MLGraphBuilder는
최대 하나의 MLGraph만
빌드할 수 있다.
MLGraph
기반 구현은 MLGraphBuilder의
오퍼레이터와 MLOperand들에
대응하는 오퍼레이터와 피연산자의 플랫폼별 표현으로 구성되지만,
이는 스크립트에 보이지 않으며 스크립트가 구성한 그래프의 합성 또는 분해일 수 있다.
MLGraph가
구성되면, MLContext.dispatch()
메서드는 CPU 실행을 위한 별도의 워커 스레드의 병렬 타임라인 또는 GPU 명령 큐의 GPU 타임라인에서
비동기적으로 그래프 실행을 수행한다. 이 메서드는 실제 실행이 다른 타임라인으로 오프로딩되는 동안
호출 스레드를 차단하지 않고 즉시 반환한다. 호출자는 MLNamedTensors를
사용하여 입력 값을 제공하며, 입력 MLOperand들을
그 값에 바인딩한다. 호출자는 또한 출력 MLOperand를
위한 MLNamedTensors도
제공한다. 이는 그래프 실행이 성공할 경우 그 결과를 포함하며, 이 결과는
MLContext.readTensor(tensor)
메서드를 사용하여 스크립트로 다시 읽어 올 수 있다. 이러한 유형의 실행은 CPU, GPU 및 NPU 장치를 지원한다.
7.2. 장치 선택
MLContext
인터페이스는 신경망 실행의 전역 상태를 나타낸다. 중요한 컨텍스트 상태 중 하나는
리소스를 관리하고 신경망 그래프의 컴파일과 최종 실행을 용이하게 하는 기반 실행 장치이다.
MLContextOptions를
사용하는 기본 생성 방법 외에도, MLContext는
애플리케이션에서 이미 사용 중인 특정 GPUDevice로부터
생성될 수도 있다.
GPU 컨텍스트가 시스템 메모리의 상수 또는 입력을 ArrayBufferView로
사용하여 그래프를 실행하는 상황에서, 입력 콘텐츠는 시스템 메모리에서 GPU 메모리로 자동 업로드되고,
그래프 실행이 끝날 때 ArrayBufferView
출력 버퍼의 시스템 메모리로 다시 다운로드된다. 이 데이터 업로드 및 다운로드 사이클은 GPU의 경우처럼
실행 장치가 데이터를 시스템 메모리 밖으로 복사하고 다시 시스템 메모리로 복사해야 할 때에만 발생한다.
장치가 CPU 장치인 경우에는 발생하지 않는다. 또한 그래프 실행의 결과는 알려진 레이아웃 형식이다.
실행은 그래프 내 중간 결과에서 네이티브 메모리 접근 패턴에 맞게 최적화될 수 있지만,
호출자의 관점에서 기대되는 동작을 유지하기 위해 그래프의 마지막 연산 출력은 그래프 끝에서
콘텐츠를 알려진 레이아웃 형식으로 다시 변환해야 한다.
MLContext가
MLContextOptions로
생성될 때, 사용자 에이전트는 이러한 옵션을 고려하여 기반 실행 장치를 선택하고 생성한다.
기반 플랫폼에 따라, 사용자 에이전트는 CPU, NPU 및 GPU 장치의 다양한 조합을 선택할 수 있다.
이 설계의 이력과 근거는 장치 선택 해설서를 참조하라.
7.3. 오퍼레이터
이 절은 비규범적이다.
WebNN API는 주요 § 2.1 애플리케이션 사용 사례를 다루는 잘 알려진 CNN 및 RNN, 트랜스포머와 생성 모델에 필요한 오퍼레이터 집합을 정의한다. 각 오퍼레이터의 세부 사항은 이 명세의 규범적 절에서 오퍼레이터 이름의 알파벳 순서로 정의된다. 이러한 오퍼레이터는 API 표면의 기능적 개요를 제공하기 위해 다음 비규범적 표에서 그 기능에 따라 범주로 그룹화된다.
참고: 일부 오퍼레이터는 여러 범주에 속한다.
예를 들어, clamp()
는 수학 함수이면서 활성화로도 사용된다.
7.4. 작업 소스
ML 작업 소스는
MLGraph들의
비동기 컴파일 및 실행과 MLContext들의
생성과 관련된 모든 작업에 사용될
작업 소스이다.
전역 객체 global과 일련의 단계 steps가 주어졌을 때, ML 작업을 큐에 넣는다는 것은 global 및 steps와 함께 ML 작업 소스에서 전역 작업을 큐에 넣는 것이다.
7.5. Permissions Policy 통합
이 명세는 문자열
"webnn"으로
식별되는 정책 제어 기능을 정의한다.
그 기본 허용 목록은 'self'이다.
8. API
8.1. navigator.ml 인터페이스
ML 객체는
Window
및 WorkerGlobalScope
컨텍스트에서 각각 Navigator
및 WorkerNavigator
인터페이스를 통해 사용할 수 있으며, navigator.ml을 통해 노출된다.
interface mixin { [NavigatorML SecureContext ,SameObject ]readonly attribute ML ; };ml Navigator includes NavigatorML ;WorkerNavigator includes NavigatorML ;
8.2. ML
인터페이스
enum MLPowerPreference {"default" ,"high-performance" ,"low-power" };dictionary {MLContextOptions MLPowerPreference powerPreference = "default";boolean accelerated =true ; }; [SecureContext ,Exposed =(Window ,Worker )]interface {ML Promise <MLContext >createContext (optional MLContextOptions options = {});Promise <MLContext >createContext (GPUDevice gpuDevice ); };
8.2.1. MLContextOptions
참고: MLContextOptions
는 활발히 개발 중이며, 더 많은 구현 경험과 더 넓은 웹 커뮤니티의 새로운 사용 사례를 바탕으로
설계가 변경될 것으로 예상된다. 워킹 그룹은 폴백 장치, 선호 순서의 여러 장치, 또는
특정 장치 제외를 정의할 수 있도록 추가 API 제어를 고려하고 있다. 논의 중인 다른
고려 사항에는 오류 처리, 최종
폴백 및 양자화된 오퍼레이터가 포함된다. 이러한 설계 고려 사항에 대한 피드백은 웹
개발자, 라이브러리 작성자, OS 및 하드웨어 벤더, 기타 이해관계자로부터 GitHub를 통해 환영한다. 핑거프린팅
고려 사항에 대한 추가 논의는 § 5 개인정보 보호 고려 사항을 참조하라.
powerPreference 옵션은 MLPowerPreference이며, 전력 소비와 관련된
애플리케이션의 선호를 나타낸다. 이는 다음 중 하나이다.
- "
default" - 사용자 에이전트가 가장 적합한 동작을 선택하게 한다.
- "
high-performance" - 전력 소비보다 실행 속도를 우선시한다.
- "
low-power" - 실행 속도와 같은 다른 고려 사항보다 전력 소비를 우선시한다.
accelerated 옵션은 대규모 병렬 가속과 관련된
애플리케이션의 선호를 나타낸다. 이 옵션은 powerPreference보다
우선순위가 낮다.
true(기본값)로 설정되면, 기반 플랫폼은 powerPreference에도
따라 GPU 또는 NPU와 같은 사용 가능한
대규모 병렬 가속기를 사용하려고 시도한다.
false로 설정되면, 애플리케이션은 CPU 추론을 선호함을 나타낸다. 예를 들어 powerPreference가
"high-performance"이고
accelerated가
false인 경우처럼 모순되는 입력이 있으면, 구현은 기반 플랫폼에서 사용 가능한 최상의
일치 항목을 선택한다(예를 들어 고성능 CPU 모드, 또는 accelerated가
powerPreference보다
우선순위가 낮으므로 이를 무시할 수 있다).
8.2.2. createContext()
-
options:MLContextOptions. 컨텍스트에 대한 애플리케이션의 선호를 제공한다. -
gpuDevice:GPUDevice. 컨텍스트와 함께 사용할 특정 장치.
MLContext.
realm realm과 options(GPUDevice
또는 MLContextOptions)가
주어졌을 때
컨텍스트를
생성한다는 것은 다음 단계를 실행하는 것이다.
-
context를 realm 내의 새
MLContext로 둔다. -
options가
GPUDevice객체이면:-
context.
[[contextType]]를 "webgpu"로 설정한다. -
context.
[[powerPreference]]를"default"로 설정한다. -
context.
[[accelerated]]를true로 설정한다.
-
-
그렇지 않으면:
-
context.
[[contextType]]를 "default"로 설정한다. -
options["
powerPreference"]가 존재하면, context.[[powerPreference]]를 options["powerPreference"]로 설정한다. -
그렇지 않으면, context.
[[powerPreference]]를"default"로 설정한다. -
options["
accelerated"]가 존재하면, context.[[accelerated]]를 options["accelerated"]로 설정한다. -
그렇지 않으면, context.
[[accelerated]]를true로 설정한다.
-
-
사용자 에이전트가 context.
[[contextType]]를 지원할 수 없다면, failure를 반환한다. -
context를 반환한다.
createContext(options) 단계는 다음과 같다.
-
global의 연관된 Document가 사용이 허용된 webnn 기능이 아니라면, realm 내의 새 promise를 "
SecurityError"DOMException으로 rejected하여 반환한다. -
promise를 realm 내의 새 promise로 둔다.
-
다음 단계를 병렬로 실행한다.
-
context를 realm 및 options가 주어졌을 때 컨텍스트를 생성한 결과로 둔다. 그 결과가 failure이면, global과 함께 ML 작업을 큐에 넣어 promise를 "
NotSupportedError"DOMException으로 reject하고, 이 단계를 중단한다. -
global과 함께 ML 작업을 큐에 넣어 promise를 context로 resolve한다.
-
-
promise를 반환한다.
createContext(gpuDevice) 메서드
단계는 다음과 같다.
-
global의 연관된 Document가 사용이 허용된 webnn 기능이 아니라면, realm 내의 새 promise를 "
SecurityError"DOMException으로 rejected하여 반환한다. -
promise를 realm 내의 새 promise로 둔다.
-
다음 단계를 병렬로 실행한다.
-
context를 realm 및 gpuDevice가 주어졌을 때 컨텍스트를 생성한 결과로 둔다. 그 결과가 failure이면, global과 함께 ML 작업을 큐에 넣어 promise를 "
NotSupportedError"DOMException으로 reject하고, 이 단계를 중단한다. -
global과 함께 ML 작업을 큐에 넣어 promise를 context로 resolve한다.
-
-
promise를 반환한다.
8.3. MLContext
인터페이스
MLContext
인터페이스는 신경망 계산 워크로드와 실행 프로세스의 전역 상태를 나타낸다. 각 MLContext 객체는
관련 컨텍스트 타입과 MLPowerPreference를
가진다.
typedef record <USVString ,MLTensor >;MLNamedTensors dictionary {MLContextLostInfo DOMString message ; }; [SecureContext ,Exposed =(Window ,Worker )]interface {MLContext undefined dispatch (MLGraph graph ,MLNamedTensors inputs ,MLNamedTensors outputs );Promise <MLTensor >createTensor (MLTensorDescriptor descriptor );Promise <MLTensor >createConstantTensor (MLOperandDescriptor descriptor ,AllowSharedBufferSource inputData );Promise <ArrayBuffer >readTensor (MLTensor tensor );Promise <undefined >readTensor (MLTensor tensor ,AllowSharedBufferSource outputData );undefined writeTensor (MLTensor tensor ,AllowSharedBufferSource inputData );MLOpSupportLimits ();opSupportLimits undefined destroy ();readonly attribute boolean accelerated ;readonly attribute Promise <MLContextLostInfo >lost ; };
MLContext는
다음 내부 슬롯을 가진다.
[[contextType]], 타입은 컨텍스트 타입.[[powerPreference]], 타입은MLPowerPreference.[[accelerated]], 타입은boolean.-
MLContext의 처리 타입(CPU 또는 대규모 병렬 처리). [[lost]], 타입은Promise<MLContextLostInfo>.[[timeline]]-
MLContext의 계산 유닛에서의 연산 실행과 관련된 타임라인. 이러한 연산에는 계산 그래프에 대한 추론과[[data]]ofMLTensor의 수정이 포함된다.이 타임라인을 더 엄밀하게 정의한다. [Issue #529]
컨텍스트 타입은 리소스를 관리하고 신경망 그래프의 컴파일 및 실행을 용이하게 하는 실행 컨텍스트의 타입이다.
- "default"
- 사용자 선호 옵션에 따라 생성된 컨텍스트.
- "webgpu"
- WebGPU 장치로부터 생성된 컨텍스트.
AllowSharedBufferSource
bufferSource 및 MLOperandDescriptor
descriptor가 주어졌을 때 디스크립터로 버퍼를 검증한다는 것은 다음 단계를 실행하는 것이다.
-
bufferSource의 바이트 길이가 descriptor의 바이트 길이와 같지 않으면 false를 반환한다.
-
bufferSource의 타입에 대해 switch한다.
ArrayBuffer-
true를 반환한다.
SharedArrayBuffer-
true를 반환한다.
ArrayBufferView-
-
bufferSource가
Uint8Array객체이면 true를 반환한다. -
bufferSource가 이 표에 따라 descriptor의
dataType과 일치하면 true를 반환한다. -
false를 반환한다.
-
참고: descriptor의 dataType과
관계없이 Uint8Array를
사용하는 것은, 예를 들어 WebAssembly.Memory
인스턴스의 일부와 같이 ArrayBuffer의
slice를 표현하는 일반적인 방법으로 지원된다. 개발자는 가독성과 유지보수성을 위해 WebNN 코드를 작성할 때
더 구체적인 뷰 타입을 사용할 것이 권장된다.
MLNamedTensors
namedTensors와 record<USVString,
MLOperandDescriptor>
namedDescriptors가 주어졌을 때 디스크립터로 텐서를 검증한다는 것은 다음과 같다.
-
namedTensors의 name → tensor 각각에 대해 반복한다.
-
tensor.
[[isConstant]]가 true이면 false를 반환한다. -
namedDescriptors[name]이 존재하지 않으면 false를 반환한다.
-
tensor.
[[descriptor]]가 namedDescriptors[name]와 같지 않으면 false를 반환한다.
-
-
true를 반환한다.
8.3.1.
dispatch()
컴파일된 MLGraph의 계산
워크로드를
MLContext의
[[timeline]]에
스케줄한다.
-
graph:MLGraph. 실행할 계산 그래프. -
inputs:MLNamedTensors. 계산 그래프의 입력. -
outputs:MLNamedTensors. 계산 그래프의 출력.
반환: undefined.
참고: dispatch() 자체는 그래프 실행이
완료되었다는 신호를 제공하지 않는다. 대신, 호출자는 출력 텐서를 다시 읽은 결과를 await할 수 있다.
아래 § 8.3.1.1 예제를 참조하라.
dispatch(graph, inputs, outputs)
메서드 단계는 다음과 같다.
-
graph.
[[context]]가 this가 아니면,TypeError를 throw한다. -
graph.
[[isDestroyed]]가 true이면, "InvalidStateError"DOMException을 throw한다. -
allTensors의 각 tensor에 대해 반복한다.
-
tensor.
[[context]]가 this가 아니면,TypeError를 throw한다. -
tensor.
[[isDestroyed]]가 true이면,TypeError를 throw한다.
-
-
inputs 및 graph.
[[inputDescriptors]]가 주어졌을 때 디스크립터로 텐서를 검증한 결과가 false를 반환하면,TypeError를 throw한다. -
outputs 및 graph.
[[outputDescriptors]]가 주어졌을 때 디스크립터로 텐서를 검증한 결과가 false를 반환하면,TypeError를 throw한다. -
다음 단계를 graph.
[[context]].[[timeline]]에 enqueue한다.-
이 단계를 실행하되, this가 lost 상태이면 중단한다.
-
inputs 및 outputs가 주어진 graph.
[[implementation]]에 compute 요청을 발행한다.그래프 실행 중 오류를 보고하기 위한 메커니즘을 추가한다. [Issue #778]
-
-
tensor를 사용하여 상수 피연산자를 생성하는 경우, build가 완료된 후 해당 tensor를 destroy하는 것은 적법하다. 구현은 컴파일된 그래프가 그러한 destruction에도 유효하게 유지되고 영향을 받지 않도록 보장할 것으로 기대된다.
8.3.1.1. 예제
다음 코드는 MLGraph를
MLTensor들을
사용해 실행하는 것을 보여준다.
const descriptor= { dataType: 'float32' , shape: [ 2 , 2 ] }; const context= await navigator. ml. createContext(); const builder= new MLGraphBuilder( context); // 1. Create a computational graph 'C = 0.2 * A + B'. const constant= builder. constant( descriptor, new Float32Array( 4 ). fill( 0.2 )); const A= builder. input( 'A' , descriptor); const B= builder. input( 'B' , descriptor); const C= builder. add( builder. mul( A, constant), B); // 2. Compile the graph. const graph= await builder. build({ 'C' : C}); // 3. Create reusable input and output tensors. const [ inputTensorA, inputTensorB, outputTensorC] = await Promise. all([ context. createTensor({ dataType: A. dataType, shape: A. shape, writable: true }), context. createTensor({ dataType: B. dataType, shape: B. shape, writable: true }), context. createTensor({ dataType: C. dataType, shape: C. shape, readable: true }) ]); // 4. Initialize the inputs. context. writeTensor( inputTensorA, new Float32Array( 4 ). fill( 1.0 )); context. writeTensor( inputTensorB, new Float32Array( 4 ). fill( 0.8 )); // 5. Execute the graph. const inputs= { 'A' : inputTensorA, 'B' : inputTensorB}; const outputs= { 'C' : outputTensorC}; context. dispatch( graph, inputs, outputs); // 6. Read back the computed result. const result= await context. readTensor( outputTensorC); console. log( 'Output value:' , new Float32Array( result)); // [1, 1, 1, 1]
8.3.2.
createTensor()
이 MLContext와
연결된 MLTensor를
생성한다.
-
descriptor:MLTensorDescriptor.
createTensor(descriptor) 메서드 단계는
다음과 같다.
-
this가 lost 상태이면, realm 내의 새 promise를 "
InvalidStateError"DOMException으로 rejected하여 반환한다. -
tensor를 MLTensor 생성의 결과로 둔다. 이때 this와 descriptor가 주어진다.
-
promise를 realm 내의 새 promise로 둔다.
-
다음 단계를 this.
[[timeline]]에 enqueue한다.-
이 단계를 실행하되, this가 lost 상태이면 중단한다:
-
descriptor가 주어졌을 때 tensor.
[[data]]를 생성하고 모든 바이트를 0으로 초기화한다. -
그것이 실패하면, global과 함께 ML 작업을 큐에 넣어 promise를 "
UnknownError"DOMException으로 reject하고, 이 단계를 중단한다. -
그렇지 않으면, global과 함께 ML 작업을 큐에 넣어 promise를 tensor로 resolve한다.
-
-
중단된 경우, global과 함께 ML 작업을 큐에 넣어 promise를 "
InvalidStateError"DOMException으로 reject한다.
-
-
promise를 반환한다.
8.3.3. createConstantTensor()
이 MLContext와
연결된 상수 MLTensor를 생성한다.
-
descriptor:MLOperandDescriptor. -
inputData:AllowSharedBufferSource. 바이트가 tensor에 기록될 버퍼.
createConstantTensor(descriptor, inputData)
메서드 단계는 다음과 같다.
-
this가 lost 상태이면, realm 내의 새 promise를 "
InvalidStateError"DOMException으로 rejected하여 반환한다. -
descriptor가 주어졌을 때 차원을 검사한 결과가 false를 반환하면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
inputData 및 descriptor가 주어졌을 때 디스크립터로 버퍼를 검증한 결과가 false를 반환하면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
bytes를 inputData가 주어졌을 때 버퍼 소스가 보유한 바이트의 복사본을 얻은 결과로 둔다.
-
tensor를 상수 MLTensor 생성의 결과로 둔다. 이때 this 및 descriptor가 주어진다.
-
promise를 realm 내의 새 promise로 둔다.
-
다음 단계를 this.
[[timeline]]에 enqueue한다.-
이 단계를 실행하되, this가 lost 상태이면 중단한다:
-
descriptor가 주어졌을 때 tensor.
[[data]]를 생성한다. -
그것이 실패하면, global과 함께 ML 작업을 큐에 넣어 promise를 "
UnknownError"DOMException으로 reject하고, 이 단계를 중단한다. -
bytes를 tensor.
[[data]]로 복사한다. -
그것이 실패하면, global과 함께 ML 작업을 큐에 넣어 promise를 "
UnknownError"DOMException으로 reject하고, 이 단계를 중단한다. -
그렇지 않으면, global과 함께 ML 작업을 큐에 넣어 promise를 tensor로 resolve한다.
-
-
중단된 경우, global과 함께 ML 작업을 큐에 넣어 promise를 "
InvalidStateError"DOMException으로 reject한다.
-
-
promise를 반환한다.
8.3.4.
readTensor(tensor)
[[data]]
of an MLTensor를
MLContext.[[timeline]]에서
스크립트로 다시 읽는다.
-
tensor:MLTensor. 읽을 tensor.
반환: Promise<ArrayBuffer>.
읽기 결과를 포함하는 버퍼.
readTensor(tensor) 메서드 단계는 다음과 같다.
-
tensor.
[[context]]가 this가 아니면, realm 내의 새 promise를TypeError로 rejected하여 반환한다. -
tensor.
[[isDestroyed]]가 true이면, realm 내의 새 promise를TypeError로 rejected하여 반환한다. -
tensor.
[[descriptor]].readable이 false이면, realm 내의 새 promise를TypeError로 rejected하여 반환한다. -
promise를 realm 내의 새 promise로 둔다.
-
promise를 tensor.
[[pendingPromises]]에 추가한다. -
다음 단계를 tensor.
[[context]].[[timeline]]에 enqueue한다.-
이 단계를 실행하되, this가 lost 상태이면 중단한다:
-
그것이 실패하면, global과 함께 ML 작업을 큐에 넣고 다음 단계를 실행한다.
-
promise를 tensor.
[[pendingPromises]]에서 제거한다. -
promise를 "
UnknownError"DOMException으로 Reject하고, 이 단계를 중단한다.
-
-
그렇지 않으면, global과 함께 ML 작업을 큐에 넣고 다음 단계를 실행한다.
-
promise를 tensor.
[[pendingPromises]]에서 제거한다. -
buffer를 realm 내에서 bytes로부터
ArrayBuffer를 생성한 결과로 둔다. -
promise를 buffer로 Resolve한다.
-
-
중단된 경우, global과 함께 ML 작업을 큐에 넣어 promise를 "
InvalidStateError"DOMException으로 reject한다.
-
-
promise를 반환한다.
8.3.5.
readTensor(tensor, outputData)
readTensor(tensor)의
Bring-your-own-buffer 변형이다.
[[data]]를
MLTensor에서
제공된 버퍼로 다시 읽어 온다.
-
tensor:MLTensor. 읽을 텐서. -
outputData:AllowSharedBufferSource. 결과를 읽어 넣을 버퍼.
readTensor(tensor, outputData)
메서드 단계는 다음과 같다:
-
tensor.
[[context]]가 this가 아니면, realm에서TypeError로 거부된 새 promise를 반환한다. -
tensor.
[[isDestroyed]]가 true이면, realm에서TypeError로 거부된 새 promise를 반환한다. -
tensor.
[[descriptor]].readable이 false이면, realm에서TypeError로 거부된 새 promise를 반환한다. -
outputData와 tensor.
[[descriptor]]가 주어졌을 때 descriptor로 버퍼 검증하기가 false를 반환하면, realm에서TypeError로 거부된 새 promise를 반환한다. -
promise를 realm의 새 promise로 둔다.
-
promise를 tensor.
[[pendingPromises]]에 추가한다. -
다음 단계를 tensor.
[[context]].[[timeline]]에 큐에 넣는다:-
이 단계를 실행하되, this가 lost 상태가 되면 중단한다:
-
그것이 실패하면, global로 ML 작업을 큐에 넣어 다음 단계를 실행한다:
-
promise를 tensor.
[[pendingPromises]]에서 제거한다. -
promise를 "
UnknownError"DOMException으로 거부하고, 이 단계를 중단한다.
-
-
그렇지 않으면, global로 ML 작업을 큐에 넣어 다음 단계를 실행한다:
-
promise를 tensor.
[[pendingPromises]]에서 제거한다. -
outputData가 detached이면, promise를
TypeError로 거부하고 이 단계를 중단한다.Note: 위의 descriptor로 버퍼 검증하기는 outputData가 detached이면 실패하지만, 그 단계와 이 단계 사이에 outputData가 detached될 수도 있다.
-
bytes를 outputData에 쓴다.
-
-
중단된 경우, global로 ML 작업을 큐에 넣어 promise를 "
InvalidStateError"DOMException으로 거부한다.
-
-
promise를 반환한다.
8.3.6.
writeTensor()
MLTensor의
[[data]]에
데이터를 MLContext의
[[timeline]]에서
쓴다.
-
tensor:MLTensor. 쓸 대상 텐서. -
inputData:AllowSharedBufferSource. 텐서에 기록될 바이트를 가진 버퍼.
반환값: undefined.
writeTensor(tensor, inputData)
메서드 단계는 다음과 같다:
-
tensor.
[[context]]가 this가 아니면,TypeError를 throw한다. -
tensor.
[[isDestroyed]]가 true이면,TypeError를 throw한다. -
tensor.
[[descriptor]].writable이 false이면,TypeError를 throw한다. -
inputData와 tensor.
[[descriptor]]가 주어졌을 때 descriptor로 버퍼 검증하기가 false를 반환하면,TypeError를 throw한다. -
bytes를 inputData가 주어졌을 때 버퍼 소스가 가진 바이트의 복사본 가져오기의 결과로 둔다.
-
Assert: bytes의 길이는 tensor.
[[descriptor]]의 byte length와 같아야 한다. -
다음 단계를 tensor.
[[context]].[[timeline]]에 큐에 넣는다:-
이 단계를 실행하되, this가 lost 상태가 되면 중단한다:
-
bytes를 tensor.
[[data]]에 복사한다.텐서에 쓰는 동안 오류를 보고하는 메커니즘을 추가한다. [Issue #778]
-
-
Note: dispatch()와 유사하게,
writeTensor() 자체는 쓰기가 완료되었다는 신호를 제공하지 않는다. 텐서의 내용을 검사하려면,
호출자는 텐서를 다시 읽은 결과를 await할 수 있다.
8.3.7.
opSupportLimits()
opSupportLimits()는
구현마다 operator 수준에서 달라지는 지원 수준을 노출한다. WebNN API의 소비자는 각 대상 플랫폼에 배포할 최적의 모델
아키텍처를 결정하기 위해 opSupportLimits()를
사용하여 기능 지원 수준을 탐지하는 것이 권장된다.
Note: opSupportLimits()
API는 브라우저 핑거프린팅을 위한 추가 엔트로피를 제공하기 위한 것이 아니다. 현재 구현에서는 이 기능 지원 정보를
OS와 브라우저 버전만으로도 추론할 수 있다. 향후 구현의 다양성이 이를 정당화한다면, 이 API는 엔트로피를 줄이기 위해
WebGPU와 유사하게 capability를 버킷화하는 등의 새로운 개인정보 보호 완화를 향후 구현에서 추가할 수 있게 한다.
핑거프린팅 고려사항에 대한 추가 논의는 § 5 개인정보 보호 고려사항을 참조하라.
8.3.7.1. MLOpSupportLimits
dictionary
MLOpSupportLimits에는
다음 최상위 멤버가 있으며, 이 외에도 각 operator에는 그
builder 메서드에 정의된 대응 멤버가 있다.
dictionary {MLOpSupportLimits MLInputOperandLayout preferredInputLayout ; [EnforceRange ]unsigned long long maxTensorByteLength ;MLTensorLimits input ;MLTensorLimits constant ;MLTensorLimits output ; };
preferredInputLayout, 타입은 MLInputOperandLayout-
conv2d()처럼 layout에 의존하는 operator를 위한 선호 입력 layout. maxTensorByteLength, 타입은 unsigned long long-
지원되는 최대 텐서 길이(바이트 단위).
input, 타입은 MLTensorLimitsconstant, 타입은 MLTensorLimitsoutput, 타입은 MLTensorLimits
8.3.7.2. MLRankRange
dictionary
dictionary {MLRankRange unsigned long min ;unsigned long max ; };
min, 타입은 unsigned long-
지원되는 최소 rank.
max, 타입은 unsigned long-
지원되는 최대 rank.
8.3.7.3. MLTensorLimits
dictionary
typedef sequence <MLOperandDataType >;MLDataTypeList dictionary {MLTensorLimits MLDataTypeList dataTypes ;MLRankRange rankRange ; };
dataTypes, 타입은 MLDataTypeList-
지원되는 데이터 타입.
rankRange, 타입은 MLRankRange-
지원되는 최소 및 최대 rank.
8.3.7.4. MLBinarySupportLimits
dictionary
dictionary {MLBinarySupportLimits MLTensorLimits a ;MLTensorLimits b ;MLTensorLimits output ; };
a, 타입은 MLTensorLimits-
a operand에 대한
MLTensorLimits. b, 타입은 MLTensorLimits-
b operand에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output operand에 대한
MLTensorLimits.
8.3.7.5. MLSingleInputSupportLimits
dictionary
dictionary {MLSingleInputSupportLimits MLTensorLimits input ;MLTensorLimits output ; };
input, 타입은 MLTensorLimits-
input operand에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output operand에 대한
MLTensorLimits.
8.3.8.
destroy()
destroy()
메서드는 context와 관련된 모든 리소스를 해제하기 위해 호출될 수 있다. 미완료 compute 요청과
MLTensor
생성/읽기/쓰기 요청은 모두 실패한다.
destroy() 메서드 단계는 다음과 같다:
8.3.9. 오류
사용자 에이전트가 MLContext가
더 이상 요청을 이행하는 데 사용할 수 없다고 판단하면, 그것에 대한 context lost 단계를 실행해야 한다.
MLContext
context에 대한 context lost
단계는 다음과 같다:
-
global을 context의 관련 전역 객체로 둔다.
-
global로 ML task를 queue하여 다음 단계를 실행한다:
-
Lose context, implementation-defined 메시지와 함께.
-
MLContext
context를 DOMString
message와 함께 lose하려면:
-
info를 새
MLContextLostInfo로 둔다. -
info.
message를 message로 설정한다. -
각
MLGraphgraph 중 graph.[[context]]가 this와 같은 것마다: -
각
MLTensortensor 중 tensor.[[context]]가 this와 같은 것마다:
message, 타입은 DOMString-
발생한 오류에 대한 정보를 제공하는 구현 정의 메시지.
MLContext는
그 [[lost]]
Promise가
settled된 경우
lost 상태이다.
8.4. MLGraph
interface
MLGraph
interface는 컴파일된 계산 그래프를 나타낸다. 일단 구성된 컴파일된 그래프는 불변이며 이후 변경할 수 없다.
[SecureContext ,Exposed =(Window ,Worker )]interface {MLGraph undefined destroy (); };
MLGraph에는
다음 내부 슬롯이 있다:
[[context]]of typeMLContext[[inputDescriptors]]of type record<USVString,MLOperandDescriptor>-
이
MLGraph의 모든 inputMLOperand에 대해, inputMLOperand의 이름을 그MLOperandDescriptor에 매핑한다. [[outputDescriptors]]of type record<USVString,MLOperandDescriptor>-
이
MLGraph의 모든 outputMLOperand에 대해, outputMLOperand의 이름을 그MLOperandDescriptor에 매핑한다. [[implementation]]-
User Agent가 제공하는 기반 구현.
[[isDestroyed]]of typeboolean-
MLGraph.destroy()메서드 단계가 실행되었는지 여부. 일단 destroy되면,MLGraph는 더 이상 사용할 수 없다.
8.4.1. destroy()
destroy()
메서드는 graph와 관련된 모든 리소스를 해제하기 위해 호출될 수 있다.
destroy() 메서드 단계는 다음과 같다:
-
this.
[[isDestroyed]]가 true이면, 이 단계를 중단한다. -
this.
[[isDestroyed]]를 true로 설정한다. -
이 graph가 소유한 리소스를 freeable로 표시하도록, this.
[[context]].[[timeline]]에 task를 큐에 넣는다.
Note: 이 graph를 사용하여 더 이상의 workload를 큐에 넣을 수 없으므로, 구현체는 이 graph를 사용해 이전에 제출된 모든 workload가 완료되면 이 graph와 관련된 추가 리소스 할당을 해제할 수 있다.
8.5. MLOperandDescriptor
dictionary
MLOperandDescriptor는
operand의 shape(차원)와 데이터 타입을 설명한다. 이는 MLGraph에 대한
input과 constant를 설명하는 데 사용되며, 모든
MLOperand는
내부 MLOperandDescriptor를
가진다.
enum {MLInputOperandLayout ,"nchw" };"nhwc" enum {MLOperandDataType ,"float32" ,"float16" ,"int32" ,"uint32" ,"int64" ,"uint64" ,"int8" };"uint8" dictionary {MLOperandDescriptor required MLOperandDataType dataType ;required sequence <[EnforceRange ]unsigned long >shape ; };
dataType, 타입은 MLOperandDataType-
operand 데이터 타입.
shape, 타입은sequence<[EnforceRange] unsigned long>-
operand 차원의 목록. 스칼라 operand의 경우 비어 있다.
MLOperandDescriptor
A는 A.dataType가
B.dataType와
같고, A.shape가
B.shape와
같으면,
MLOperandDescriptor
B와 같다.
MLOperandDataType
dataType와 list shape가 주어졌을 때 MLOperandDescriptor
만들기를 하려면, 다음 단계를 실행한다:
-
descriptor를 새
MLOperandDescriptor로 둔다. -
descriptor.
dataType를 dataType로 설정한다. -
descriptor를 반환한다.
MLOperandDescriptor
desc의 byte length는 다음 단계가 반환하는 값이다:
-
elementLength를 1로 둔다.
-
desc.
shape의 각 dimension에 대해 반복한다:-
elementLength를 elementLength * dimension으로 설정한다.
-
-
elementSize를 desc.
dataType과 이 표에 따라 일치하는ArrayBufferView타입 중 하나의 element size로 둔다. -
elementLength * elementSize를 반환한다.
MLOperandDescriptor
desc의 element count는 다음 단계가 반환하는 값이다:
유효한 차원은
0보다 크고 long의
범위에 있는 정수이다.
구현체는 더 작은 상한을 부과할 수 있다.
유효한 텐서 개수는 0보다 크고 8192 이하인 정수이다. 구현체는 더 작은 상한을 부과할 수 있다.
0-size 차원을 지원해야 하는가? [Issue #391]
MLOperandDescriptor
descriptor가 주어졌을 때 차원 검사를 하려면, 다음 단계를
실행한다:
-
descriptor.
shape의 size가 구현에서 지원하기에 너무 크면, false를 반환한다.operand 차원의 최대 개수는 정의되어 있지 않지만, native ML API에는 보통 최대 지원 크기가 있다. [Issue #456]
-
descriptor의 element count가 유효한 차원이 아니면, false를 반환한다.
-
descriptor의 byte length가 구현에서 지원되지 않으면, false를 반환한다.
-
true를 반환한다.
8.6. MLOperand
interface
MLOperand는
operation의 일부를 완전히 구성된 operation으로 합성한 결과로 구성 중인 중간 graph를 나타낸다.
예를 들어, MLOperand는
operation에 입력되는 constant 또는 여러 constant를 operation으로 결합한 결과를 나타낼 수 있다.
§ 7 Programming Model도 참조하라.
[SecureContext ,Exposed =(Window ,Worker )]interface {MLOperand readonly attribute MLOperandDataType dataType ;readonly attribute FrozenArray <unsigned long >shape ; };dictionary {MLOperatorOptions USVString label = ""; };typedef (bigint or unrestricted double )MLNumber ;
MLOperand에는
다음 내부 슬롯이 있다:
[[builder]]of typeMLGraphBuilder-
MLOperand의 연결된 builder 객체. [[descriptor]]of typeMLOperandDescriptor-
MLOperand의 descriptor. [[name]]of type string-
MLOperand의 이름(input operand에 대해서만). [[operator]]of type operator[[constantTensor]]of typeMLTensor-
MLOperand의 tensor(constant operand에 대해서만).
An MLOperand의
dataType는 그 [[descriptor]].dataType이다.
An MLOperand의
shape는 그 [[descriptor]].shape이다.
An MLOperand의
rank는 그 shape의 size이다.
dataType getter 단계는
this의 dataType를 반환한다.
shape getter 단계는
this의 shape를 반환한다.
[[builder]]
객체는 MLGraphBuilder()
생성자에 의해 MLContext
객체에 바인딩되므로, MLOperand도
항상 동일한 MLContext
객체에 바인딩된다.
어떤 operation이 MLOperandDataType의
하위 집합만 지원하는 경우, 위치 인수와 options를 모두 포함한 각 operation 입력 operand의 허용되는 데이터
타입은 명시적인 MLOperandDataType의
목록, 또는 operand의 dataType가 다른 입력 operand의 dataType와 동일해야 한다는 제약, 또는 임의의
MLOperandDataType를
허용하는 임의로 주어진다.
구현체는 명시된 것보다 더 적은 operand 데이터 타입을 지원할 수 있지만, 적어도 명시된 필수 데이터
타입은 지원해야 한다. 지원 여부는 opSupportLimits()
메서드를 MLContext에서
사용하고, 현재 Chromium 프로토타입의 ONNX Runtime, LiteRT 및 CoreML 백엔드 전반에서 해당 operation 멤버의 dataTypes
값을 검사하여 각 operation별로 질의할 수 있다.
필수 데이터 타입 집합은 다양한 플랫폼 전반의 구현 경험을 바탕으로 결정되었으며, 개발자가 이러한 데이터 타입만 사용하도록 모델을 설계함으로써 상호 운용 가능한 콘텐츠를 만들 수 있게 한다. 이 명세의 Web Platform Tests는 이 capability detection 메커니즘을 사용해 모든 허용되는 데이터 타입에 대한 올바른 동작을 검증하지만, 필수 데이터 타입만 지원해도 통과할 수 있다.
어떤 operation이 특정 rank를 가진 입력 operand를 요구하는 경우, 위치 인수와 options를 모두 포함한 각 operation 입력 operand의 허용되는 rank는 명시적인 rank(예: 1), 또는 임의의 차원 수를 허용하는 N, 또는 다른 operand와 동일한 것으로 주어진다. 입력 operand의 shape가 다른 입력 operand에 대해 단방향으로 브로드캐스트 가능해야 하거나, 다른 입력 operand와 양방향으로 브로드캐스트 가능해야 하는 경우처럼, 더 구체적인 제약도 흔하며, 이런 경우 허용되는 rank는 범위로 나열되고, 구체적인 유효성 검사는 해당 operation의 단계에서 주어진다.
구현체는 operand의 rank에 대해 명시된
것보다 더 제한적인 하한 및/또는
상한을 부과할 수 있지만, 적어도 명시된 필수
rank는 지원해야 한다. 지원 여부는 opSupportLimits()
메서드를 MLContext에서
사용하고, 현재 Chromium 프로토타입의 ONNX Runtime, LiteRT 및 CoreML 백엔드 전반에서 해당 operation 멤버의 rankRange.min
및 rankRange.max
값을 검사하여 각 operation별로 질의할 수 있다.
필수 rank 집합은 다양한 플랫폼 전반의 구현 경험을 바탕으로 결정되었으며, 개발자가 이러한 rank만 가진 입력 operand로 구성되도록 모델을 설계함으로써 상호 운용 가능한 콘텐츠를 만들 수 있게 한다.
MLOperatorOptions에는
다음 멤버가 있다:
label, 타입은 USVString이며, 기본값은""-
MLGraphBuilder메서드를 사용해MLOperand를 생성하는 operator가 만들어질 때 선택적으로 제공된다. 구현체는 이 값을 사용해 operator의 label을 초기화할 수 있다.
Note: label은 자연어 문자열을 의도한 것이 아니다.
이는 변수 이름이나 오류 코드와 유사한, 언어 독립적인 식별자이며, 예를 들어
"mul#1234" 같은 것이다.
Note: 구현체는 개발자가 제공한 label을
사용하여 오류 메시지를 향상하고 디버깅 가능성을 높이는 것이 권장되며, 여기에는 그래프 구성 중의 동기 오류와 비동기 build()
메서드 중 발생하는 오류가 모두 포함된다.
개발자가 label을
통해 제공한 label을 디버깅 도구, 로그 또는 오류 메시지에 표시할 때, 구현체는 악의적인 유니코드 시퀀스 주입 같은
보안 위험을 방지하기 위해 출력을 정화해야 한다. 예를 들어 양방향 텍스트
스푸핑 [UTR36], 소스 코드 스푸핑 [UTS55] 및
기타 우려가 이에 해당한다. 예를 들어 구현체는 제어 문자(예: U+202A
~ U+202E, U+2066 ~ U+2069)를 이스케이프하거나 필터링하거나, 잠재적
스푸핑을 무력화하기 위해 안전한 렌더링 메커니즘을 사용해야 한다.
8.6.1. MLOperand
만들기
MLOperand
객체는 MLGraphBuilder의
메서드들에 의해 만들어지며, 내부적으로 다음 알고리즘을 사용한다.
MLGraphBuilder
builder와 MLOperandDescriptor
desc가 주어졌을 때
MLOperand 만들기를 하려면, 다음 단계를 실행한다:
-
realm을 builder의 관련 realm으로 둔다.
-
operand를 realm의 새
MLOperand로 둔다. -
operand.
[[builder]]를 builder로 설정한다. -
operand.
[[descriptor]]를 desc로 설정한다. -
operand를 반환한다.
MLOperand
operand가 주어졌을 때
MLOperand 복사하기를 하려면, 다음 단계를 실행한다:
-
builder를 operand.
[[builder]]로 둔다. -
realm을 builder의 관련 realm으로 둔다.
-
result를 realm의 새
MLOperand로 둔다. -
result.
[[builder]]를 builder로 설정한다. -
result.
[[descriptor]]를 operand.[[descriptor]]로 설정한다. -
operand.
[[name]]이 존재하면, result.[[name]]을 operand.[[name]]으로 설정한다. -
result를 반환한다.
MLGraphBuilder
builder와 MLOperand
operand가 주어졌을 때 operand 검증를 하려면, operand.[[builder]]가
builder이면 true를, 그렇지 않으면 false를 반환한다.
8.6.1.1.
MLNumber
MLNumber는 모든 MLOperandDataType일
수 있는 MLOperand에
대한 numeric option의 타입을 지정할 때 사용된다. 여기에는 64-bit integer 타입("uint64"
및 "int64")과
32-bit floating point("float32")가
모두 포함된다.
구현체는 해당 MLOperandDataType에
따라 값을 처리한다.
예를 들어, clamp(input, options)가
dataType이 "uint32"인
MLOperand로
호출되면, MLNumber
매개변수는 명시적으로 unsigned long으로
cast된다.
bigint와
numeric types의 union에 대한 지원은 [WEBIDL]에서 새로 도입되었으며, 구현 지원도 제한적이다.
프로토타입 구현체는 이 접근 방식에 대한 피드백을 제공하는 것이 권장된다. [whatwg/webidl Issue #1388]
8.7. MLTensorDescriptor
딕셔너리
MLTensorDescriptor는
MLTensor의 특성과
기능을 설명한다.
dictionary :MLTensorDescriptor MLOperandDescriptor {boolean readable =false ;boolean writable =false ; };
readable, 타입은 boolean, 기본값은false-
tensor의 내용을
readTensor(tensor)또는readTensor(tensor, outputData)를 통해 읽을 수 있는지 여부. writable, 타입은 boolean, 기본값은false-
tensor의 내용을
writeTensor()를 통해 쓸 수 있는지 여부.
8.8. MLTensor
인터페이스
MLTensor
인터페이스는 MLGraph의
입력 또는 출력으로 사용될 수 있는 tensor를 나타낸다. MLTensor를
뒷받침하는 메모리는 그것을 생성하는 데 사용된 MLContext와
MLTensorDescriptor의
요구 사항에 따라 구현 정의 방식으로 할당되어야 한다.
MLTensor의
[[data]]와
관련된 연산은 연결된 MLContext의
[[timeline]]에서
발생한다.
MLTensor가 어떻게
할당되는지에 대한 구현 정의 요구 사항에는, 메모리가 특정 바이트 정렬로
할당되거나 특정 메모리 풀에 할당되어야 한다는 등의 제약이 포함될 수 있다.
[SecureContext ,Exposed =(Window ,Worker )]interface {MLTensor readonly attribute MLOperandDataType dataType ;readonly attribute FrozenArray <unsigned long >shape ;readonly attribute boolean readable ;readonly attribute boolean writable ;readonly attribute boolean constant ;undefined destroy (); };
MLTensor는
다음 내부 슬롯을 가진다.
[[context]], 타입은MLContext-
MLTensor의 연결된 컨텍스트. [[descriptor]], 타입은MLTensorDescriptor-
MLTensor의 디스크립터. [[pendingPromises]], 타입은Promise들의 set-
진행 중이며 아직 resolve되지 않은
MLContext.readTensor(tensor)메서드 호출에 대응하는 Promise들. 모든 pending promise는MLTensor가 destroy될 때 reject된다. [[isDestroyed]], 타입은boolean-
MLTensor.destroy()단계가 실행되었는지 여부. destroy된 후에는MLTensor를 더 이상 사용할 수 없다. [[data]], 구현 정의 타입-
MLTensor를 뒷받침하는 바이트들. 이 데이터는[[context]].[[timeline]]에서만 접근하거나 수정될 수 있다. [[isConstant]], 타입은boolean-
MLTensor가 상수 MLTensor 생성에 의해 생성되었는지 여부.
MLTensor의
dataType은 그 [[descriptor]]의
dataType이다.
MLTensor의
shape는 그 [[descriptor]]의
shape이다.
dataType getter 단계는
this의 dataType을 반환하는 것이다.
shape getter 단계는
this의 shape를 반환하는 것이다.
readable getter 단계는
this.[[descriptor]].readable를
반환하는 것이다.
writable getter 단계는
this.[[descriptor]].writable를
반환하는 것이다.
constant getter 단계는
this의
[[isConstant]]를
반환하는 것이다.
8.8.1. MLTensor
생성하기
MLTensor는
연결된 MLContext에 의해
생성된다.
MLContext
context 및 MLTensorDescriptor
descriptor가 주어졌을 때 MLTensor를
생성한다는 것은 다음 단계를 실행하는 것이다.
-
realm을 context의 관련 realm으로 둔다.
-
tensor를 realm 내의 새
MLTensor로 둔다. -
tensor.
[[context]]를 context로 설정한다. -
tensor.
[[descriptor]]를 descriptor로 설정한다. -
tensor.
[[isDestroyed]]를 false로 설정한다. -
tensor.
[[isConstant]]를 false로 설정한다. -
tensor를 반환한다.
8.8.2. destroy()
MLTensor와 관련된
리소스를 해제한다. 이 메서드는 멱등적이다.
undefined.
destroy() 메서드 단계는 다음과 같다.
-
this.
[[isDestroyed]]를 true로 설정한다. -
this.
[[pendingPromises]]의 각 promise에 대해 반복한다:-
this.
[[pendingPromises]]에서 promise를 제거한다. -
promise를 "
InvalidStateError"DOMException으로 Reject한다.
-
-
다음 단계를 this.
[[context]].[[timeline]]에 enqueue한다.
참고: 이 tensor를 사용하여 더 이상 연산을 enqueue할 수 없으므로, 구현은 이전에 제출된 이 tensor 사용 연산이 모두 완료된 후 이 tensor와 관련된 추가 리소스 할당을 해제할 수 있다.
8.8.3.
상수 MLTensor
생성하기
상수 MLTensor는
연결된 MLContext에 의해
생성된다.
MLContext
context, MLOperandDescriptor
inputDescriptor가 주어졌을 때 상수
MLTensor를 생성한다는 것은 다음 단계를 실행하는 것이다.
-
realm을 context의 관련 realm으로 둔다.
-
tensor를 realm 내의 새
MLTensor로 둔다. -
tensor.
[[context]]를 context로 설정한다. -
tensorDescriptor를 새
MLTensorDescriptor로 둔다. -
tensorDescriptor.
readable를 false로 설정한다. -
tensorDescriptor.
writable을 false로 설정한다. -
tensor.
[[descriptor]]를 tensorDescriptor로 설정한다. -
tensor.
[[isDestroyed]]를 false로 설정한다. -
tensor.
[[isConstant]]를 true로 설정한다. -
tensor를 반환한다.
8.9. MLGraphBuilder
인터페이스
MLGraphBuilder
인터페이스는 § 2 사용 사례에서 식별된, 계산 그래프로 합성될 수 있는
일련의 연산을 정의한다. 또한 그래프 빌딩 세션의 중간 상태를 나타낸다.
typedef record <USVString ,MLOperand >; [MLNamedOperands SecureContext ,Exposed =(Window ,Worker )]interface { // Construct the graph builder from the context.MLGraphBuilder constructor (MLContext context ); // Create an operand for a graph input.MLOperand input (USVString name ,MLOperandDescriptor descriptor ); // Create an operand for a graph constant.MLOperand constant (MLOperandDescriptor descriptor ,AllowSharedBufferSource buffer ); // Create a scalar operand from the specified number of the specified type.MLOperand constant (MLOperandDataType dataType ,MLNumber value ); // Create an operand from a specified constant tensor.MLOperand constant (MLTensor tensor ); // Compile the graph up to the specified output operands asynchronously.Promise <MLGraph >build (MLNamedOperands outputs ); };
MLGraphBuilder.build()
메서드는 그래프 빌더 상태를 지정된 출력 피연산자까지, 이를 생성한 MLContext의 타입에
따라 컴파일된 그래프로 컴파일한다. MLContext의
[[contextType]]가
"default"로 설정되어
있으면, 컴파일된 그래프는
MLGraph가
반환되기 직전에 초기화된다. 이 그래프 초기화 단계는 이후 그래프 실행의 최적 성능을 위해 중요하다.
이는 일반적으로 "가중치 전처리"로 알려진 과정을 포함하며, 여기서는 그래프에 대한 모든 상수 입력이
전처리되어 이후 그래프 실행 호출을 위해 운영 체제 수준에서 캐시된다. 초기화 입력은 일반적으로
그래프 구성 시 상수 피연산자로서 constant()
메서드를 통해 지정된 상수 가중치 데이터이다.
MLGraphBuilder는
다음 내부 슬롯을 가진다.
[[context]], 타입은MLContext-
이
MLGraphBuilder와 연결된MLContext타입의 컨텍스트. [[hasBuilt]], 타입은boolean-
MLGraphBuilder.build()가 호출되었는지 여부. 한 번 빌드되면MLGraphBuilder는 더 이상 오퍼레이터를 생성하거나MLGraph를 컴파일할 수 없다.
8.9.1.
MLGraphBuilder
생성자
-
context:MLContext.MLGraphBuilder와 연결할 컨텍스트.
new MLGraphBuilder(context)
생성자 단계는 다음과 같다.
-
this의 관련 전역 객체의 연관된 Document가 사용이 허용된 webnn 기능이 아니라면, "
SecurityError"DOMException을 throw한다. -
context가 lost 상태이면, "
InvalidStateError"DOMException을 throw한다. -
this.
[[context]]를 context로 설정한다. -
this.
[[hasBuilt]]를 false로 설정한다.
8.9.2. 입력 피연산자
입력으로 사용할 수 있는, 디스크립터를 기반으로 한 이름 있는 MLOperand를
생성한다.
-
name: 입력의 이름인 string. -
descriptor:MLOperandDescriptor객체.
MLOperand.
input(name, descriptor)
메서드 단계는 다음과 같다.
MLGraphBuilder
API는 입력 피연산자 없이 MLGraph를
생성할 수 있게 한다. 기반 플랫폼이 이를 지원하지 않으면, 구현은 stub 입력을 추가하거나 상수를 그래프에 대한
입력으로 전달할 수 있다.
8.9.3. 상수 피연산자
MLGraphBuilder
메서드에서 사용할 수 있는 상수 MLOperand를 생성한다.
8.9.3.1. constant(descriptor, buffer)
초기화 데이터를 포함하는, 지정된 데이터 타입과 shape의 상수 MLOperand를
생성한다.
-
descriptor:MLOperandDescriptor. 출력 tensor의 디스크립터. -
buffer:AllowSharedBufferSource. 초기화 데이터를 포함하는 버퍼.
MLOperand.
상수 출력 tensor.
constant(descriptor, buffer)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
descriptor가 주어졌을 때 차원을 검사한 결과가 false를 반환하면,
TypeError를 throw한다. -
buffer와 descriptor가 주어졌을 때 디스크립터로 버퍼를 검증한 결과가 false를 반환하면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
operand를 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
bytes를 buffer가 주어졌을 때 버퍼 소스가 보유한 바이트의 복사본을 얻은 결과로 둔다.
-
-
operand를 반환한다.
8.9.3.2. constant(tensor)
초기화된 데이터를 포함하는, 지정된 데이터 타입과 shape의 상수 MLOperand를
생성한다.
constant(tensor) 메서드
단계는 다음과 같다.
-
tensor.
[[context]]가 this.[[context]]가 아니면,TypeError를 throw한다. -
tensor.
[[isDestroyed]]가 true이면,TypeError를 throw한다. -
tensor.
[[isConstant]]가 false이면,TypeError를 throw한다. -
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
그래프 연결 만들기:
-
operand를 this와 tensor.
[[descriptor]]가 주어졌을 때 MLOperand를 생성한 결과로 둔다. -
operand.
[[constantTensor]]를 tensor로 설정한다.
-
-
operand를 반환한다.
8.9.3.3. constant(dataType, value)
지정된 값과 데이터 타입의 스칼라 상수 MLOperand를
생성한다.
"int8"
데이터 타입에 할당되는 경우 등이 그렇다.
-
dataType:MLOperandDataType. -
value:MLNumber. 상수의 값.
MLOperand.
상수 출력.
constant(dataType, value)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
value를 dataType으로 캐스팅한 결과로 설정한다.
-
descriptor를 dataType 및 « »가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
operand를 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
-
operand를 반환한다.
8.9.4. build 메서드
주어진 출력 피연산자까지 합성된 그래프를 비동기적으로 계산 그래프로 빌드한다.-
outputs:MLNamedOperands. 그래프의 출력이 될MLOperand들을 식별한다.
MLGraph>.
build(outputs) 메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, realm 내의 새 promise를 "
InvalidStateError"DOMException으로 rejected하여 반환한다. -
outputs가 비어 있으면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
outputs의 각 name → operand에 대해 반복한다:
-
name이 비어 있으면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
피연산자를 검증한 결과가 this와 operand가 주어졌을 때 false를 반환하면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
operand가 this의 graph의 inputs 또는 constants 안에 있으면, realm 내의 새 promise를
TypeError로 rejected하여 반환한다. -
operand.
[[constantTensor]]가 존재하고 operand.[[constantTensor]].[[isDestroyed]]가 true이면, realm 내의 새 promise를TypeError로 rejected하여 반환한다.
-
-
operands를 새 빈 set으로 둔다.
-
operators를 새 빈 set으로 둔다.
-
inputs를 새 빈 set으로 둔다.
-
queue가 비어 있지 않은 동안:
-
graph를 realm 내의 새
MLGraph로 둔다. -
graph.
[[context]]를 this.[[context]]로 설정한다. -
graph.
[[isDestroyed]]를 false로 설정한다. -
inputs 내의 각 operand에 대해 반복한다:
-
graph.
[[inputDescriptors]][operand.[[name]]]를 operand.[[descriptor]]로 설정한다.
-
-
outputs의 각 name → operand에 대해 반복한다:
-
graph.
[[outputDescriptors]][name]을 operand.[[descriptor]]로 설정한다.
-
-
this.
[[hasBuilt]]를 true로 설정한다. -
promise를 realm 내의 새 promise로 둔다.
-
다음 단계를 graph.
[[context]].[[timeline]]에 enqueue한다.-
이 단계를 실행하되, graph.
[[context]]가 lost 상태이면 중단한다:-
graphImpl을 this의 graph를 operands, operators, inputs, outputs의 값, 그리고 graph.
[[context]].[[powerPreference]]및 graph.[[context]].[[accelerated]]와 함께, 기반 플랫폼에서 해석할 수 있는 구현 정의 형식으로 변환한 결과로 둔다. -
이전 단계가 실패하면, global과 함께 ML 작업을 큐에 넣어 promise를 "
OperationError"DOMException으로 reject하고, 이 단계를 중단한다. -
graph.
[[implementation]]을 graphImpl로 설정한다. -
global과 함께 ML 작업을 큐에 넣어 promise를 graph로 resolve한다.
-
-
중단된 경우, global과 함께 ML 작업을 큐에 넣어 promise를 "
InvalidStateError"DOMException으로 reject한다.
-
-
promise를 반환한다.
참고: 입력 피연산자 또는 상수 피연산자를 그래프 output으로
지정하면 오류가 발생한다. 이는 보통 API를 잘못 사용한 것이기 때문이다. 호출자는 identity()
오퍼레이터를 도입하여 이를 우회할 수 있다.
8.9.5. argMin/argMax 연산
축을 따라 모든 입력 값 중 최소값 또는 최대값의 인덱스 위치를 반환한다. 동률인 경우, 반환 값의 식별은 구현에 따라 달라진다.dictionary :MLArgMinMaxOptions MLOperatorOptions {boolean keepDimensions =false ;MLOperandDataType outputDataType = "int32"; };partial interface MLGraphBuilder {MLOperand argMin (MLOperand input , [EnforceRange ]unsigned long axis ,optional MLArgMinMaxOptions options = {});MLOperand argMax (MLOperand input , [EnforceRange ]unsigned long axis ,optional MLArgMinMaxOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits argMin ;MLSingleInputSupportLimits argMax ; };
MLArgMinMaxOptions는
다음 멤버를 가진다.
keepDimensions, 타입은 boolean, 기본값은false-
true이면, 축소된 차원을 크기 1로 유지한다.
outputDataType, 타입은 MLOperandDataType, 기본값은"int32"-
MLOperandDataType. 출력 데이터 타입.
-
input:MLOperand. 입력 N-D tensor. -
axis: 축소할 차원. 값은 입력 tensor의 rank를 N이라고 할 때 [0, N-1] 범위에 있어야 한다. -
options: 선택적MLArgMinMaxOptions. 연산의 선택적 매개변수.
반환: MLOperand.
keepDimensions가
true이면 input의
rank와 같은
rank를 가진 출력 N-D
tensor이며,
keepDimensions가
false이면 input의
rank - 1이다.
값은 outputDataType
타입이어야 하며, axis로
지정된 입력 차원의 크기를 N이라고 할 때 [0, N-1] 범위에 있어야 한다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
| output | "int32",
"int64"
| "int32"
| N | 0부터 5까지 |
MLOpSupportLimits는
argMin()
및 argMax()에
대해 다음 멤버를 가진다.
argMin, 타입은 MLSingleInputSupportLimits-
argMin()오퍼레이터에 대한 지원 제한. argMax, 타입은 MLSingleInputSupportLimits-
argMax()오퍼레이터에 대한 지원 제한.
string
op, MLOperand
input, unsigned long
axis, 및 MLArgMinMaxOptions
options가 주어졌을 때 argMin/argMax 연산을 생성한다는
것은
다음 단계를 실행하는 것이다.
-
Assert: op는 "argMin", "argMax" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 피연산자를 검증한 결과가 false를 반환하면,
TypeError를 throw한다. -
options.
outputDataType이 (이 표에 따른) 출력 tensor의 허용되는 데이터 타입이 아니면,TypeError를 throw한다. -
input의 shape[axis]가 options.
outputDataType의 최대값보다 크면,TypeError를 throw한다. -
outputShape를 input의 shape, « axis », 및 options.
keepDimensions가 주어졌을 때 축소 출력 크기를 계산한 결과로 둔다. 그것이 failure를 반환하면,TypeError를 throw한다. -
desc를 options.
outputDataType및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다. -
그래프 연결 만들기:
-
operator를 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
다음 argMin/argMax 알고리즘이 지원된다.
argMin(input, axis, options)
메서드 단계는 다음과 같다.
-
output을 "argMin", input, axis 및 options가 주어졌을 때 argMin/argMax 연산을 생성한 결과로 둔다.
-
output을 반환한다.
argMax(input, axis, options)
메서드 단계는 다음과 같다.
-
output을 "argMax", input, axis 및 options가 주어졌을 때 argMin/argMax 연산을 생성한 결과로 둔다.
-
output을 반환한다.
8.9.6. batchNormalization
[Batch-Normalization]을 사용하여 입력 tensor의 값을 정규화한다. 각 입력 feature에 대해, 모델이 훈련되는 동안 해당 feature의 mean 및 variance 값은 batch 차원의 모든 sample에 걸쳐 계산된다. 그런 다음 이 mean 및 variance 값은 이후 모델 추론 중에 이 연산에 제공된다.dictionary :MLBatchNormalizationOptions MLOperatorOptions {MLOperand scale ;MLOperand bias ; [EnforceRange ]unsigned long axis = 1;double epsilon = 1e-5; };partial interface MLGraphBuilder {MLOperand batchNormalization (MLOperand input ,MLOperand mean ,MLOperand variance ,optional MLBatchNormalizationOptions options = {}); };dictionary {MLBatchNormalizationSupportLimits MLTensorLimits input ;MLTensorLimits mean ;MLTensorLimits variance ;MLTensorLimits scale ;MLTensorLimits bias ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLBatchNormalizationSupportLimits batchNormalization ; };
MLBatchNormalizationOptions는
다음 멤버를 가진다.
scale, 타입은 MLOperandbias, 타입은 MLOperandaxis, 타입은 unsigned long, 기본값은1-
mean 및 variance 값이 대응되는 입력 shape의 feature 수 차원에 대한 인덱스. 그 값은 입력 tensor의 rank를 N이라고 할 때 [0, N-1] 범위에 있어야 한다. 기본값은 1이며,
"nchw"데이터 layout에서 channel("c") 차원에 대응한다. epsilon, 타입은 double, 기본값은1e-5-
0으로 나눔으로 인한 계산 오류를 방지하기 위한 작은 값.
-
input:MLOperand. 입력 N-D tensor. -
mean:MLOperand. batch 전체에 걸친 입력 feature의 mean 값의 1-D tensor를 지정한다. 그 크기는axis가 나타내는 입력 차원의 크기와 같다. -
variance:MLOperand. batch 전체에 걸친 입력 feature의 variance 값의 1-D tensor이며, 그 크기는axis가 나타내는 입력 차원의 크기와 같다. -
options: 선택적MLBatchNormalizationOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
input과
같은 shape의 batch-normalized N-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 1부터 N까지 | 3부터 5까지 |
mean
| input과
동일
| "float32",
"float16"
| 1 | 1 |
variance
| input과
동일
| "float32",
"float16"
| 1 | 1 |
scale
| input과
동일
| "float32",
"float16"
| 1 | 1 |
bias
| input과
동일
| "float32",
"float16"
| 1 | 1 |
| output | input과
동일
| "float32",
"float16"
| input과
동일
| 3부터 5까지 |
MLBatchNormalizationSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. mean, 타입은 MLTensorLimits-
mean 피연산자에 대한
MLTensorLimits. variance, 타입은 MLTensorLimits-
variance 피연산자에 대한
MLTensorLimits. scale, 타입은 MLTensorLimits-
scale 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
batchNormalization()에
대해 다음 멤버를 가진다.
batchNormalization, 타입은 MLBatchNormalizationSupportLimits-
batchNormalization()오퍼레이터에 대한 지원 제한.
batchNormalization(input, mean, variance, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, mean, variance, options.
scale(존재하는 경우), 그리고 options.bias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false이면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
axis가 0부터 input의 rank까지의 범위 안에 없으면(상한 제외),TypeError를 throw한다. -
mean의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
mean의 shape가 « input의 shape[options.
axis] »와 같지 않으면,TypeError를 throw한다. -
variance의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
variance의 shape가 « input의 shape[options.
axis] »와 같지 않으면,TypeError를 throw한다. -
options.
epsilon을 options.epsilon을 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
operator를 input, mean, variance 및 options가 주어진 "batchNormalization" operation의 operator로 둔다.
-
output을 this와 input.
[[descriptor]]가 주어졌을 때 MLOperand 만들기의 결과로 둔다. -
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input, mean 및 variance로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
입력 tensor가 "nchw"
layout의 4-D인 경우 이 연산의 동작은, user agent가 일반적으로 더 효율적인 구현을 가지고 있지만,
다음과 같이 다른 연산의 사용으로 일반적으로 에뮬레이트될 수 있다. 기반 플랫폼이 어떤 연산을
직접 지원하지 않는 경우, 이 분해는 구현을 안내하기 위한 템플릿으로 사용할 수 있다.
function batchNormalization( builder, input, mean, variance, options) { const shape= [ 1 , input. shape[ options. axis], 1 , 1 ]; return builder. add( builder. mul( builder. reshape( options. scale, shape), builder. div( builder. sub( input, builder. reshape( mean, shape)), builder. sqrt( builder. add( builder. reshape( variance, shape), builder. constant( input. dataType, options. epsilon))))), builder. reshape( options. bias, shape)); }
8.9.7. cast
입력 tensor의 각 element를 대상 데이터 타입으로 캐스팅한다.partial interface MLGraphBuilder {MLOperand cast (MLOperand input ,MLOperandDataType dataType ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits cast ; };
-
input:MLOperand. 입력 N-D tensor. -
dataType:MLOperandDataType. 대상 데이터 타입. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
각 element가 대상 데이터 타입으로 캐스팅된,
input과
같은 shape의 N-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32",
"int8",
"uint8"
| N | 0부터 5까지 |
| output | 임의 | "float32",
"float16",
"int32",
"int8",
"uint8"
| input과
동일
| 0부터 5까지 |
MLOpSupportLimits에는
cast()에
대해 다음 멤버가 있다:
cast, 타입은 MLSingleInputSupportLimits-
cast()operator에 대한 지원 제한.
MLOperandDataType들
사이의 casting은 다음 표에 따라 일부 경우에는 지정되어 있고, 다른 경우에는 구현
정의이다:
| 대상 타입 입력 타입 |
"float32",
"float16"
|
"int32",
"uint32",
"int64",
"uint64",
"int8",
"uint8"
|
|---|---|---|
"float32",
"float16"
|
범위 안에 있으면, 표현 가능한 가장 가까운 값.
범위를 벗어나면, +/-Infinity. |
범위 안에 있으면, 잘라낸 값.
범위를 벗어나면, 구현 정의. |
"int32",
"uint32",
"int64",
"uint64",
"int8",
"uint8"
|
범위 안에 있으면, 표현 가능한 가장 가까운 값.
범위를 벗어나면, +/-Infinity. |
범위 안에 있으면, 같은 값.
범위를 벗어나면, signed 타입에 대해 two’s complement를 가정하여 최하위 N비트를 대상 타입으로 재해석한다. |
NOTE: 예를 들어, "int8"에서
"uint8"로
-1을 casting하면 255가 산출되도록 지정되어 있다. 그러나 "float32"에서
"uint8"로
-1을 casting하는 것은 구현 정의이다.
cast(input, dataType, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false이면,
TypeError를 throw한다. -
dataType이 (이 표에 따른) output tensor의 허용되는 데이터 타입이 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
operator를 dataType 및 options가 주어진 "cast" operation의 operator로 둔다.
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.8. clamp
최솟값과 최댓값으로 지정된 범위 안에서 입력 tensor를 element-wise로 clamp한다.dictionary :MLClampOptions MLOperatorOptions {MLNumber minValue ;MLNumber maxValue ; };partial interface MLGraphBuilder {MLOperand clamp (MLOperand input ,optional MLClampOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits clamp ; };
MLClampOptions는
다음 멤버를 가진다.
minValue, 타입은 MLNumber-
범위의 최솟값. 지정되지 않으면, 범위의 하한에 대한 clamping은 수행되지 않는다.
maxValue, 타입은 MLNumber-
범위의 최댓값. 지정되지 않으면, 범위의 상한에 대한 clamping은 수행되지 않는다.
-
input:MLOperand. 입력 tensor. -
options: 선택적MLClampOptions. 연산의 선택적 매개변수.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16"
| N | 0부터 5까지 |
| output | input과
동일
| "float32",
"float16"
| input과
동일
| 0부터 5까지 |
MLOpSupportLimits는
clamp()에
대해 다음 멤버를 가진다.
clamp, 타입은 MLSingleInputSupportLimits-
clamp()오퍼레이터에 대한 지원 제한.
clamp(input, options) 메서드
단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
minValue를 주어졌다면 options.
minValue로, 그렇지 않으면 Infinity로 둔다. -
options.
minValue를 minValue를 input의 dataType으로 캐스팅한 결과로 설정한다. -
maxValue를 주어졌다면 options.
maxValue로, 그렇지 않으면 -Infinity로 둔다. -
options.
maxValue를 maxValue를 input의 dataType으로 캐스팅한 결과로 설정한다. -
options.
minValue가 options.maxValue보다 크면,TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "clamp" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은, user agent가 일반적으로 더 효율적인 구현을 가지고 있지만, 다음과 같이 다른 연산의 사용으로 일반적으로 에뮬레이트될 수 있다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하기 위한 템플릿으로 사용할 수 있다.
function clamp( builder, input, options) { if ( options. minValue=== undefined ) { if ( options. maxValue=== undefined ) { return input; } else { return builder. min( input, builder. constant( input. dataType, options. maxValue)); } } else { if ( options. maxValue=== undefined ) { return builder. max( input, builder. constant( input. dataType, options. minValue)); } else { return builder. min( builder. max( input, builder. constant( input. dataType, options. minValue)), builder. constant( input. dataType, options. maxValue)); } } }
8.9.9. concat
주어진 축을 따라 입력 tensor들을 연결한다.partial interface MLGraphBuilder {MLOperand concat (sequence <MLOperand >inputs , [EnforceRange ]unsigned long axis ,optional MLOperatorOptions options = {}); };dictionary {MLConcatSupportLimits MLTensorLimits inputs ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLConcatSupportLimits concat ; };
-
inputs: sequence<MLOperand>. 모든 입력 tensor는, 연결할 차원의 크기를 제외하고 같은 shape를 가져야 한다. -
axis:unsigned longscalar. 입력들이 연결되는 축. 그 값은 입력 tensor들의 rank를 N이라고 할 때 [0, N-1] 범위에 있어야 한다. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
모든 입력을 axis를
따라 연결한 tensor.
출력 tensor는 모든 입력이 연결된 차원을 제외하고 같은 shape를 가진다.
해당 차원의 크기는 같은 차원의 모든 입력 크기의 합으로 계산된다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
inputs의
items
| 임의 | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
| output | inputs의
items와
동일
| "float32",
"float16",
"int32"
| inputs의
items와
동일
| 1부터 5까지 |
MLConcatSupportLimits는
다음 멤버를 가진다.
inputs, 타입은 MLTensorLimits-
모든 input 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
concat()에
대해 다음 멤버를 가진다.
concat, 타입은 MLConcatSupportLimits-
concat()오퍼레이터에 대한 지원 제한.
concat(inputs, axis, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 inputs 안의 어떤 item이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
inputs size가 유효한 tensor 수가 아니면,
TypeError를 throw한다. -
first를 inputs[0]으로 둔다.
-
desc를 first의 dataType 및 first의 shape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 inputs, axis, 및 options가 주어진 "concat" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 inputs로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.10. conv2d
4-D input 및 filter tensor가 주어졌을 때 2-D convolution을 계산한다enum {MLConv2dFilterOperandLayout ,"oihw" ,"hwio" ,"ohwi" };"ihwo" dictionary :MLConv2dOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >padding ;sequence <[EnforceRange ]unsigned long >strides ;sequence <[EnforceRange ]unsigned long >dilations ; [EnforceRange ]unsigned long groups = 1;MLInputOperandLayout inputLayout = "nchw";MLConv2dFilterOperandLayout filterLayout = "oihw";MLOperand bias ; };partial interface MLGraphBuilder {MLOperand conv2d (MLOperand input ,MLOperand filter ,optional MLConv2dOptions options = {}); };dictionary {MLConv2dSupportLimits MLTensorLimits input ;MLTensorLimits filter ;MLTensorLimits bias ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLConv2dSupportLimits conv2d ; };
MLConv2dOptions는
다음 멤버를 가진다.
padding, 타입은sequence<[EnforceRange] unsigned long>-
길이 4의 list: [beginningHeight, endingHeight, beginningWidth, endingWidth]. convolution input의 각 spatial dimension의 시작과 끝에 추가되는 행과 열을 지정한다. 기본값은 [0, 0, 0, 0]이다.
strides, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [strideHeight, strideWidth]. convolution input의 각 spatial dimension에 대한 sliding window의 stride를 지정한다. 기본값은 [1, 1]이다.
dilations, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [dilationHeight, dilationWidth]. convolution filter(kernel)에 적용되는 각 spatial dimension의 dilation factor를 지정한다. 기본값은 [1, 1]이다.
groups, 타입은 unsigned long, 기본값은1-
input channel과 output channel을 나누는 그룹 수.
inputLayout, 타입은 MLInputOperandLayout, 기본값은"nchw"-
입력 및 출력 tensor의 layout 형식을 다음과 같이 지정한다.
filterLayout, 타입은 MLConv2dFilterOperandLayout, 기본값은"oihw"-
filter tensor의 layout 형식을 다음과 같이 지정한다.
bias, 타입은 MLOperand-
convolution 결과에 더해질 값들을 가지는, [outputChannels] shape의 추가 1-D tensor.
-
input:MLOperand. 입력 4-D tensor. 논리적 shape는inputLayout의 값에 따라 해석된다. -
filter:MLOperand. filter 4-D tensor. 논리적 shape는filterLayout의 값 및groups에 따라 해석된다. -
options:MLConv2dOptions. 연산의 선택적 매개변수.
반환: MLOperand.
convolution 결과를 포함하는 출력 4-D tensor. 출력 shape는
inputLayout에
따라 해석된다.
더 구체적으로, "nchw"
input layout에 대한 출력 tensor의 spatial dimension 또는 마지막 두 차원의 크기는 다음과 같이
계산할 수 있다.
outputSize = 1 + (inputSize - (filterSize - 1) * dilation - 1 + beginningPadding + endingPadding) / stride
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 4 | 4 |
filter
| input과
동일
| "float32",
"float16"
| 4 | 4 |
bias
| input과
동일
| "float32",
"float16"
| 1 | 1 |
| output | input과
동일
| "float32",
"float16"
| 4 | 4 |
MLConv2dSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. filter, 타입은 MLTensorLimits-
filter 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
conv2d()에
대해 다음 멤버를 가진다.
conv2d, 타입은 MLConv2dSupportLimits-
conv2d()오퍼레이터에 대한 지원 제한.
groups
= inputChannels = outputChannels이며, filter tensor의 shape는 "oihw"
layout의 경우 [options.groups, 1, height, width], "hwio"
layout의 경우 [height, width, 1, options.groups], "ohwi"
layout의 경우 [options.groups, height, width, 1], 그리고 "ihwo"
layout의 경우 [1, height, width, options.groups]이다.
unsigned integer inputSize, filterSize, beginningPadding, endingPadding, stride 및 dilation이 주어졌을 때 conv output size를 계산한다는 것은 다음 단계를 수행하는 것이다. 이는 number를 반환한다.
-
effectiveFilterSize를 ( filterSize - 1 ) * dilation + 1로 둔다.
-
outputSize를 ( inputSize - effectiveFilterSize + beginningPadding + endingPadding ) / stride + 1로 둔다.
-
outputSize를 반환한다.
unsigned integer inputHeight, inputWidth, filterHeight 및 filterWidth, 4개의 unsigned integer로 된 list padding, 2개의 unsigned integer로 된 list strides, 그리고 2개의 unsigned integer로 된 list dilations가 주어졌을 때 conv2d output size를 계산한다는 것은 다음 단계를 수행하는 것이다. 이는 두 number의 list를 반환한다.
-
outputHeight를 inputHeight, filterHeight, padding[0], padding[1], strides[0] 및 dilations[0]이 주어졌을 때 conv output size를 계산한 결과로 둔다.
-
outputWidth를 inputWidth, filterWidth, padding[2], padding[3], strides[1] 및 dilations[1]이 주어졌을 때 conv output size를 계산한 결과로 둔다.
-
« outputHeight, outputWidth »를 반환한다.
conv2d(input, filter, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, filter, 그리고 options.
bias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
filter의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그렇지 않고, options.
dilations의 size가 2가 아니면,TypeError를 throw한다. -
output shape 계산하기:
-
inputShape를 input의 shape로 둔다.
-
options.
inputLayout에 따라 분기한다: -
filterShape를 filter의 shape로 둔다.
-
options.
filterLayout에 따라 분기한다:"hwio"-
« filterHeight, filterWidth, filterInputChannels, outputChannels »를 filterShape로 둔다.
"ohwi"-
« outputChannels, filterHeight, filterWidth, filterInputChannels »를 filterShape로 둔다.
"ihwo"-
« filterInputChannels, filterHeight, filterWidth, outputChannels »를 filterShape로 둔다.
"oihw"-
« outputChannels, filterInputChannels, filterHeight, filterWidth »를 filterShape로 둔다.
-
그렇지 않고, inputChannels / options.
groups가 filterInputChannels와 같지 않으면,TypeError를 throw한다. -
outputChannels % options.
groups가 0이 아니면,TypeError를 throw한다. -
outputHeight, outputWidth »를 inputHeight, inputWidth, filterHeight, filterWidth, options.
padding, options.strides, 그리고 options.dilations가 주어졌을 때 conv2d output sizes 계산하기의 결과로 둔다. -
outputHeight를 floor( outputHeight )로 설정한다.
-
outputWidth를 floor( outputWidth )로 설정한다.
-
outputHeight 또는 outputWidth 중 어느 하나라도 유효한 차원이 아니면,
TypeError를 throw한다. -
options.
inputLayout에 따라 분기한다: -
desc를 input의 dataType와 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options와 filter가 주어진 "conv2d" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 filter로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.11. convTranspose2d
4-D input 및 filter tensor가 주어졌을 때 2-D transposed convolution을 계산한다enum {MLConvTranspose2dFilterOperandLayout ,"iohw" ,"hwoi" };"ohwi" dictionary :MLConvTranspose2dOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >padding ;sequence <[EnforceRange ]unsigned long >strides ;sequence <[EnforceRange ]unsigned long >dilations ;sequence <[EnforceRange ]unsigned long >outputPadding ;sequence <[EnforceRange ]unsigned long >outputSizes ; [EnforceRange ]unsigned long groups = 1;MLInputOperandLayout inputLayout = "nchw";MLConvTranspose2dFilterOperandLayout filterLayout = "iohw";MLOperand bias ; };partial interface MLGraphBuilder {MLOperand convTranspose2d (MLOperand input ,MLOperand filter ,optional MLConvTranspose2dOptions options = {}); };partial dictionary MLOpSupportLimits {MLConv2dSupportLimits convTranspose2d ; };
MLConvTranspose2dOptions는
다음 멤버를 가진다.
padding, 타입은sequence<[EnforceRange] unsigned long>-
길이 4의 list: [beginningHeight, endingHeight, beginningWidth, endingWidth]. convolution input의 각 spatial dimension의 시작과 끝에 추가되는 행과 열을 지정한다. 기본값은 [0, 0, 0, 0]이다.
strides, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [strideHeight, strideWidth]. convolution input의 각 spatial dimension에 대한 sliding window의 stride를 지정한다. 기본값은 [1, 1]이다.
dilations, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [dilationHeight, dilationWidth]. convolution filter(kernel)에 적용되는 각 spatial dimension의 dilation factor를 지정한다. 기본값은 [1, 1]이다.
outputPadding, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list. 출력 tensor의 각 spatial dimension에 적용되는 padding 값을 지정한다. 명시적인 padding 값은
strides의 값이 1보다 클 때 transposed convolution의 출력 tensor shape를 명확히 하기 위해 필요하다.이 값들은 필요할 때 출력 shape를 명확히 하기 위해서만 사용되며, 반드시 어떤 padding 값이 출력 tensor에 쓰이게 하는 것은 아니라는 점에 유의한다.
기본값은 [0, 0]이다.
outputSizes, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list. 출력 tensor의 마지막 두 차원의 크기를 지정한다. 출력 크기가 명시적으로 지정되면,
outputPadding의 output padding 값은 무시된다.지정되지 않으면, 출력 크기는 자동으로 계산된다.
groups, 타입은 unsigned long, 기본값은1-
input channel과 output channel을 나누는 그룹 수.
inputLayout, 타입은 MLInputOperandLayout, 기본값은"nchw"-
입력 및 출력 tensor의 layout 형식을 다음과 같이 지정한다.
filterLayout, 타입은 MLConvTranspose2dFilterOperandLayout, 기본값은"iohw"-
filter tensor의 layout 형식을 다음과 같이 지정한다.
bias, 타입은 MLOperand-
convolution 결과에 더해질 값들을 가지는, [outputChannels] shape의 추가 1-D tensor.
-
input:MLOperand. 입력 4-D tensor. 논리적 shape는inputLayout의 값에 따라 해석된다. -
filter:MLOperand. filter 4-D tensor. 논리적 shape는filterLayout의 값 및groups에 따라 해석된다. -
options: 선택적MLConvTranspose2dOptions.
반환: MLOperand.
transposed convolution 결과를 포함하는 출력 4-D tensor. 출력 shape는
inputLayout에
따라 해석된다.
더 구체적으로, outputSizes가
명시적으로 지정되지 않는 한, 출력 tensor의 spatial dimension 값을 다음과 같이 계산하려면
outputPadding이
필요하다.
outputSize = (inputSize - 1) * stride + (filterSize - 1) * dilation + 1 - beginningPadding - endingPadding + outputPadding
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 4 | 4 |
filter
| 동일 input
| "float32",
"float16"
| 4 | 4 |
bias
| 동일 input
| "float32",
"float16"
| 1 | 1 |
| output | 동일 input
| "float32",
"float16"
| 4 | 4 |
MLOpSupportLimits는
convTranspose2d()에
대해 다음 멤버를 가진다.
convTranspose2d, 타입은 MLConv2dSupportLimits-
convTranspose2d()오퍼레이터에 대한 지원 제한.
unsigned integer inputSize, filterSize, beginningPadding, endingPadding, stride, 및 dilation이 주어졌을 때 convtranspose output size를 계산한다는 것은 다음 단계를 수행하는 것이다. 이는 number를 반환한다.
-
effectiveFilterSize를 ( filterSize - 1 ) * dilation + 1로 둔다.
-
outputSize를 ( inputSize - 1 ) * stride + effectiveFilterSize - beginningPadding - endingPadding로 둔다.
-
outputSize를 반환한다.
convTranspose2d(input, filter, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, filter, 그리고 options.
bias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
filter의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그렇지 않고, options.
dilations의 size가 2가 아니면,TypeError를 throw한다. -
options.
outputPadding이 존재하지 않으면, 이를 list « 0, 0 »로 설정한다. -
그렇지 않고, options.
outputPadding의 size가 2가 아니면,TypeError를 throw한다. -
options.
outputSizes가 존재하면: -
그렇지 않으면:
-
options.
outputPadding[0]이 options.strides[0]보다 크거나 같거나, 또는 options.outputPadding[1]이 options.strides[1]보다 크거나 같으면,TypeError를 throw한다.
-
-
output shape 계산하기:
-
inputShape를 input의 shape로 둔다.
-
options.
inputLayout에 따라 분기한다: -
filterShape를 filter의 shape로 둔다.
-
options.
filterLayout에 따라 분기한다: -
inputChannels가 filterInputChannels와 같지 않으면,
TypeError를 throw한다. -
outputChannels를 filterOutputChannels * options.
groups로 둔다. -
calculatedOutputHeight를 inputHeight, filterHeight, padding[0], padding[1], strides[0] 및 dilations[0]이 주어졌을 때 convtranspose output size 계산하기의 결과로 둔다.
-
calculatedOutputWidth를 inputWidth, filterWidth, padding[2], padding[3], strides[1] 및 dilations[1]이 주어졌을 때 convtranspose output size 계산하기의 결과로 둔다.
-
options.
outputSizes가 존재하면:-
« outputHeight, outputWidth »를 options.
outputSizes로 둔다. -
outputHeight가 calculatedOutputHeight보다 작거나, outputHeight가 calculatedOutputHeight + strides[0]보다 크거나 같으면,
TypeError를 throw한다. -
outputWidth가 calculatedOutputWidth보다 작거나, outputWidth가 calculatedOutputWidth + strides[1]보다 크거나 같으면,
TypeError를 throw한다.
-
-
그렇지 않으면:
-
outputHeight를 calculatedOutputHeight + options.
outputPadding[0]으로 둔다. -
outputWidth를 calculatedOutputWidth + options.
outputPadding[1]로 둔다.
-
-
outputHeight 또는 outputWidth 중 어느 하나라도 유효한 차원이 아니면,
TypeError를 throw한다. -
options.
inputLayout에 따라 분기한다: -
desc를 input의 dataType와 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options와 filter가 주어진 "convTranspose2d" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 filter로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.12. cumulativeSum
주어진 axis를 따라 일련의 값들의 누적 합을 계산하며, 현재 값을 포함하거나 제외할 수 있다.dictionary :MLCumulativeSumOptions MLOperatorOptions {boolean exclusive =false ;boolean reversed =false ; };partial interface MLGraphBuilder {MLOperand cumulativeSum (MLOperand input ,unsigned long axis ,optional MLCumulativeSumOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits cumulativeSum ; };
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int32",
"uint32",
"int64",
"uint64"
| "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 1부터 5까지 |
MLCumulativeSumOptions는
다음 멤버를 가진다.
exclusive, 타입은 boolean, 기본값은false-
출력에 현재 값을 포함할지 제외할지 여부. 즉, inclusive prefix sum 또는 exclusive prefix sum [Prefix-sum]을 의미한다. input [1,2,3,4]가 주어졌을 때, inclusive summation은 [1,3,6,10]의 출력을 산출하는 반면 exclusive는 [0,1,3,6]을 산출한다. 기본값은 inclusive이다.
reversed, 타입은 boolean, 기본값은false-
active axis를 따라 합산 방향을 반대로 하여 높은 coordinate에서 낮은 coordinate로 시작할지 여부. input [1,2,3,4]가 주어졌을 때, inclusive forward summation은 [1,3,6,10]의 출력을 산출하는 반면 inclusive backward summation은 [10,9,7,4]를 산출한다. 기본값은 forward이다.
-
input:MLOperand. 입력 tensor. -
axis:unsigned longscalar. summation이 수행될 axis. 그 값은 N이input의 rank일 때 [0, N-1] 범위 안에 있어야 한다. -
options:MLCumulativeSumOptions. 연산의 선택적 매개변수를 지정한다.
반환:
MLOpSupportLimits는
cumulativeSum()에
대해 다음 멤버를 가진다.
cumulativeSum, 타입은 MLSingleInputSupportLimits-
cumulativeSum()오퍼레이터에 대한 지원 제한.
cumulativeSum(input, axis, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 "cumulativeSum" 연산 및 options에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.13. Element-wise 이항 연산
두 입력 tensor의 element-wise 이항 덧셈, 뺄셈, 곱셈, 나눗셈, 거듭제곱, 최댓값 및 최솟값을 계산한다.연산은 broadcast되며, [numpy-broadcasting-rule]를 따른다. 입력 tensor들은 bidirectionally broadcastable이어야 한다. 출력 tensor의 rank는 입력 tensor들의 최대 rank이다. 출력 tensor의 각 dimension에 대해, 그 크기는 입력 tensor들의 해당 dimension을 따라 가장 큰 크기이다.
partial interface MLGraphBuilder {MLOperand add (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand sub (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand mul (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand div (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand max (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand min (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand pow (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLBinarySupportLimits add ;MLBinarySupportLimits sub ;MLBinarySupportLimits mul ;MLBinarySupportLimits div ;MLBinarySupportLimits max ;MLBinarySupportLimits min ;MLBinarySupportLimits pow ; };
-
a:MLOperand. 첫 번째 입력 tensor. -
b:MLOperand. 두 번째 입력 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
두 입력 tensor의 element-wise 이항 연산 결과를 포함하는 출력 tensor.
-
add: 두 입력 tensor의 값을 element-wise로 더한다.
-
sub: 첫 번째 입력 tensor의 값에서 두 번째 입력 tensor의 값을 element-wise로 뺀다.
-
mul: 두 입력 tensor의 값을 element-wise로 곱한다.
-
div: 첫 번째 입력 tensor의 값을 두 번째 tensor의 값으로 element-wise로 나눈다. integer 타입은 0 방향으로 truncate된다.
-
max: 두 입력 tensor의 값 중 더 큰 값을 element-wise로 선택한다.
-
min: 두 입력 tensor의 값 중 더 작은 값을 element-wise로 선택한다.
-
pow: 첫 번째 입력 tensor의 값을 두 번째 입력 tensor의 값으로 거듭제곱한 값을 element-wise로 계산한다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| 임의 | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
b
| a와
동일
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | a와
동일
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
MLOpSupportLimits는
element-wise 이항 연산에 대해 다음 멤버를 가진다.
add, 타입은 MLBinarySupportLimits-
add()오퍼레이터에 대한 지원 제한. sub, 타입은 MLBinarySupportLimits-
sub()오퍼레이터에 대한 지원 제한. mul, 타입은 MLBinarySupportLimits-
mul()오퍼레이터에 대한 지원 제한. div, 타입은 MLBinarySupportLimits-
div()오퍼레이터에 대한 지원 제한. max, 타입은 MLBinarySupportLimits-
max()오퍼레이터에 대한 지원 제한. min, 타입은 MLBinarySupportLimits-
min()오퍼레이터에 대한 지원 제한. pow, 타입은 MLBinarySupportLimits-
pow()오퍼레이터에 대한 지원 제한.
string
op, MLOperand
a, MLOperand
b, 및 MLOperatorOptions
options가 주어졌을 때 element-wise
이항 연산을 생성하려면, 다음 단계를 실행한다.
-
Assert: op는 "add", "sub", "mul", "div", "max", "min", "pow" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 a 또는 b 중 어느 하나가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
outputShape를 a의 shape와 b의 shape를 bidirectionally broadcasting한 결과로 둔다.
-
descriptor를 a의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 a, b, 및 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 a 및 b로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
element-wise 이항 연산 알고리즘은 다음과 같이 element-wise 이항 연산을 생성하는 단계를 호출한다.
add(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "add", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
sub(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "sub", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
mul(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "mul", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
div(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "div", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
max(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "max", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
min(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "min", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
pow(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "pow", a, b, 및 options가 주어졌을 때 element-wise 이항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
8.9.14. Element-wise 논리 연산
input tensor들을 element-wise로 비교하고, 비교에 대해 0(false) 또는 1(true) 값을 가지는"uint8"
tensor를 반환한다. 단일 피연산자 연산의 경우, 해당 연산의 논리 결과를 반환한다.
여러 피연산자 연산의 경우, 연산은 broadcast되며 [numpy-broadcasting-rule]를 따른다. 입력 tensor들은 bidirectionally broadcastable이어야 한다. 출력 tensor의 rank는 입력 tensor들의 최대 rank이다. 출력 tensor의 각 dimension에 대해, 그 크기는 입력 tensor들의 해당 dimension을 따라 가장 큰 크기이다.
partial interface MLGraphBuilder {MLOperand equal (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand notEqual (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand greater (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand greaterOrEqual (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand lesser (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand lesserOrEqual (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand logicalNot (MLOperand a ,optional MLOperatorOptions options = {});MLOperand logicalAnd (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand logicalOr (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand logicalXor (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {});MLOperand isNaN (MLOperand a ,optional MLOperatorOptions options = {});MLOperand isInfinite (MLOperand a ,optional MLOperatorOptions options = {}); };dictionary {MLLogicalNotSupportLimits MLTensorLimits a ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLBinarySupportLimits equal ;MLBinarySupportLimits notEqual ;MLBinarySupportLimits greater ;MLBinarySupportLimits greaterOrEqual ;MLBinarySupportLimits lesser ;MLBinarySupportLimits lesserOrEqual ;MLLogicalNotSupportLimits logicalNot ;MLBinarySupportLimits logicalAnd ;MLBinarySupportLimits logicalOr ;MLBinarySupportLimits logicalXor ;MLLogicalNotSupportLimits isNaN ;MLLogicalNotSupportLimits isInfinite ; };
-
a:MLOperand. 첫 번째 입력 tensor. -
b:MLOperand. 지정된 경우 두 번째 입력 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
두 입력 tensor의 element-wise 비교 결과를 포함하는 출력 tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| 임의 | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
b
| a와
동일
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | "uint8"
| "uint8"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| "uint8"
| "uint8"
| N | 0부터 5까지 |
| output | "uint8"
| "uint8"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| "uint8"
| "uint8"
| N | 0부터 5까지 |
b
| a와
동일
| "uint8"
| N | 0부터 5까지 |
| output | "uint8"
| "uint8"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| 임의 | "float32",
"float16"
| N | 0부터 5까지 |
| output | "uint8"
| "uint8"
| N | 0부터 5까지 |
MLLogicalNotSupportLimits에는
다음 멤버가 있다:
a, 타입은 MLTensorLimits-
a operand에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output operand에 대한
MLTensorLimits.
MLOpSupportLimits에는
element-wise logical operation에 대해 다음 멤버가 있다:
equal, 타입은 MLBinarySupportLimits-
equal()operator에 대한 지원 제한. notEqual, 타입은 MLBinarySupportLimits-
notEqual()operator에 대한 지원 제한. greater, 타입은 MLBinarySupportLimits-
greater()operator에 대한 지원 제한. greaterOrEqual, 타입은 MLBinarySupportLimits-
greaterOrEqual()operator에 대한 지원 제한. lesser, 타입은 MLBinarySupportLimits-
lesser()operator에 대한 지원 제한. lesserOrEqual, 타입은 MLBinarySupportLimits-
lesserOrEqual()operator에 대한 지원 제한. logicalNot, 타입은 MLLogicalNotSupportLimits-
logicalNot()operator에 대한 지원 제한. logicalAnd, 타입은 MLBinarySupportLimits-
logicalAnd()operator에 대한 지원 제한. logicalOr, 타입은 MLBinarySupportLimits-
logicalOr()operator에 대한 지원 제한. logicalXor, 타입은 MLBinarySupportLimits-
logicalXor()operator에 대한 지원 제한. isNaN, 타입은 MLLogicalNotSupportLimits-
isNaN()operator에 대한 지원 제한. isInfinite, 타입은 MLLogicalNotSupportLimits-
isInfinite()operator에 대한 지원 제한.
-
equal: 두 input tensor의 값이 같은지 element-wise로 비교한다.
-
notEqual: 두 input tensor의 값이 같지 않은지 element-wise로 비교한다.
-
greater: 첫 번째 input tensor의 값이 더 큰지 element-wise로 비교한다.
-
greaterOrEqual: 첫 번째 input tensor의 값이 더 크거나 같은지 element-wise로 비교한다.
-
lesser: 첫 번째 input tensor의 값이 더 작은지 element-wise로 비교한다.
-
lesserOrEqual: 첫 번째 input tensor의 값이 더 작거나 같은지 element-wise로 비교한다.
-
logicalNot: input tensor의 값을 element-wise로 0 또는 1의 값으로 반전한다. 구체적으로 input 값이 0이 아니면 0으로 반전한다. 반대로 0인 input 값은 1로 반전한다.
-
logicalAnd: 두 input tensor의 logical and를 element-wise로 계산하며, 0이 아닌 모든 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
logicalOr: 두 input tensor의 logical or를 element-wise로 계산하며, 0이 아닌 모든 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
logicalXor: 두 input tensor의 logical xor를 element-wise로 계산하며, 0이 아닌 모든 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
isNaN: input tensor의 값이 유효하지 않은 숫자 표현(NaN)인지 element-wise로 확인하며, NaN에는 1을, 그 외에는 0을 반환한다.
-
isInfinite: input tensor의 값이 infinite인지 element-wise로 확인하며, 양의 무한대 또는 음의 무한대에는 1을, 그 외에는 0을 반환한다.
greaterOrEqual()
및 lesserOrEqual()
operation은 각각 logicalNot(),
lesser(),
및 greater()
operation으로 구현할 수 있지만(즉 builder.greaterOrEqual(a, b)는
builder.logicalNot(builder.lesser(a, b))임), NaN 사례를 처리하고
성능상의 이유로 이중 비교를 피하기 위해 특별히 정의되어 있다.
string
op, MLOperand
a, optional MLOperand
b, 그리고 MLOperatorOptions
options가 주어졌을 때, element-wise
logical operation 만들기를 하려면 다음 단계를 실행한다:
-
Assert: op는 "equal", "notEqual", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "logicalNot", "logicalAnd", "logicalOr", "logicalXor", "isNaN", "isInfinite" 중 하나이다.
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 a로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
op가 "logicalNot", "logicalAnd", "logicalOr", "logicalXor" 중 하나이면:
-
op가 "isNaN", "isInfinite" 중 하나이면:
-
b가 전달되었으면:
-
그렇지 않으면:
-
descriptor를
"uint8"및 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다. -
graph 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 a와 (b가 전달되었으면) b, 그리고 options가 주어진 op operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 a 및 (b가 전달되었으면) b로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
element-wise 논리 연산 알고리즘은 다음과 같이 element-wise 논리 연산을 생성하는 단계를 호출한다.
equal(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "equal", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
notEqual(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "notEqual", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
greater(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "greater", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
greaterOrEqual(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "greaterOrEqual", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
lesser(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "lesser", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
lesserOrEqual(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "lesserOrEqual", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
logicalNot(a, options)
메서드 단계는 다음과 같다.
-
output을 "logicalNot", a, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
logicalAnd(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "logicalAnd", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
logicalOr(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "logicalOr", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
logicalXor(a, b, options)
메서드 단계는 다음과 같다.
-
output을 "logicalXor", a, b, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
isNaN(a, options) 메서드
단계는 다음과 같다.
-
output을 "isNaN", a, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
isInfinite(a, options)
메서드 단계는 다음과 같다.
-
output을 "isInfinite", a, 및 options가 주어졌을 때 element-wise 논리 연산을 생성한 결과로 둔다.
-
output을 반환한다.
8.9.15. Element-wise 단항 연산
input tensor에 대한 element-wise 단항 연산을 계산한다.partial interface MLGraphBuilder {MLOperand abs (MLOperand input ,optional MLOperatorOptions options = {});MLOperand ceil (MLOperand input ,optional MLOperatorOptions options = {});MLOperand cos (MLOperand input ,optional MLOperatorOptions options = {});MLOperand erf (MLOperand input ,optional MLOperatorOptions options = {});MLOperand exp (MLOperand input ,optional MLOperatorOptions options = {});MLOperand floor (MLOperand input ,optional MLOperatorOptions options = {});MLOperand identity (MLOperand input ,optional MLOperatorOptions options = {});MLOperand log (MLOperand input ,optional MLOperatorOptions options = {});MLOperand neg (MLOperand input ,optional MLOperatorOptions options = {});MLOperand reciprocal (MLOperand input ,optional MLOperatorOptions options = {});MLOperand roundEven (MLOperand input ,optional MLOperatorOptions options = {});MLOperand sin (MLOperand input ,optional MLOperatorOptions options = {});MLOperand sign (MLOperand input ,optional MLOperatorOptions options = {});MLOperand sqrt (MLOperand input ,optional MLOperatorOptions options = {});MLOperand tan (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits abs ;MLSingleInputSupportLimits ceil ;MLSingleInputSupportLimits cos ;MLSingleInputSupportLimits erf ;MLSingleInputSupportLimits exp ;MLSingleInputSupportLimits floor ;MLSingleInputSupportLimits identity ;MLSingleInputSupportLimits log ;MLSingleInputSupportLimits neg ;MLSingleInputSupportLimits reciprocal ;MLSingleInputSupportLimits roundEven ;MLSingleInputSupportLimits sin ;MLSingleInputSupportLimits sign ;MLSingleInputSupportLimits sqrt ;MLSingleInputSupportLimits tan ; };
-
input:MLOperand. 입력 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
input tensor의 element-wise 단항 연산 결과를 포함하는 출력 tensor. 출력 tensor의 shape는 input
tensor의 shape와 같다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
element-wise unary operation에 대해 다음 멤버가 있다:
abs, 타입은 MLSingleInputSupportLimits-
abs()operator에 대한 지원 제한. ceil, 타입은 MLSingleInputSupportLimits-
ceil()operator에 대한 지원 제한. cos, 타입은 MLSingleInputSupportLimits-
cos()operator에 대한 지원 제한. erf, 타입은 MLSingleInputSupportLimits-
erf()operator에 대한 지원 제한. exp, 타입은 MLSingleInputSupportLimits-
exp()operator에 대한 지원 제한. floor, 타입은 MLSingleInputSupportLimits-
floor()operator에 대한 지원 제한. identity, 타입은 MLSingleInputSupportLimits-
identity()operator에 대한 지원 제한. log, 타입은 MLSingleInputSupportLimits-
log()operator에 대한 지원 제한. neg, 타입은 MLSingleInputSupportLimits-
neg()operator에 대한 지원 제한. reciprocal, 타입은 MLSingleInputSupportLimits-
reciprocal()operator에 대한 지원 제한. roundEven, 타입은 MLSingleInputSupportLimits-
roundEven()operator에 대한 지원 제한. sin, 타입은 MLSingleInputSupportLimits-
sin()operator에 대한 지원 제한. sign, 타입은 MLSingleInputSupportLimits-
sign()operator에 대한 지원 제한. sqrt, 타입은 MLSingleInputSupportLimits-
sqrt()operator에 대한 지원 제한. tan, 타입은 MLSingleInputSupportLimits-
tan()operator에 대한 지원 제한.
-
abs: input tensor의 절댓값을 element-wise로 계산한다.
-
ceil: input tensor의 ceiling을 element-wise로 계산한다.
-
cos: input tensor의 cosine을 element-wise로 계산한다.
-
erf: input tensor의 error function [Error-Function]을 element-wise로 계산한다.
-
exp: input tensor의 exponential을 element-wise로 계산한다.
-
floor: input tensor의 floor를 element-wise로 계산한다.
-
identity: input tensor의 값을 output tensor로 element-wise로 복사한다.
-
log: input tensor의 자연로그를 element-wise로 계산한다.
-
neg: input tensor의 수치적 음수 값을 element-wise로 계산한다.
-
reciprocal: input tensor의 역수를 element-wise로 계산한다.
-
roundEven: input tensor를 절반값은 가장 가까운 짝수 값으로 element-wise로 반올림한다 (예: [0.1, 0.9, 1.1, 1.9, -3.5, -2.5, -1.5, 1.5, 2.5, 3.5]는 [0.0, 1.0, 1.0, 2.0, -4.0, -2.0, -2.0, 2.0, 2.0, 4.0]을 산출한다).
-
sin: input tensor의 sine을 element-wise로 계산한다.
-
sign: input tensor의 sign(-1, 0, 1)을 element-wise로 계산하며, > 0이면 1, < 0이면 -1, 그 외에는 0을 반환한다.
-
sqrt: input tensor의 square root를 element-wise로 계산한다.
-
tan: input tensor의 tangent를 element-wise로 계산한다.
string
op, MLOperand
input, optional list allowedDataTypes, 그리고 options가 주어졌을 때,
element-wise
unary operation 만들기를 하려면 다음 단계를 실행한다:
-
Assert: op는 "abs", "ceil", "cos", "erf", "exp", "floor", "identity", "log", "neg", "reciprocal", "roundEven", "sin", "sign", "sqrt", "tan" 중 하나이다.
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
allowedDataTypes가 주어졌고 그것이 input의 dataType을 contain하지 않으면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 op operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
element-wise unary operation 알고리즘은 다음과 같이 element-wise unary operation 만들기 단계를 호출한다.
abs(input, options) 메서드
단계는 다음과 같다:
ceil(input, options) 메서드
단계는 다음과 같다:
-
output을 "ceil", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
cos(input, options) 메서드
단계는 다음과 같다:
-
output을 "cos", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
erf(input, options) 메서드
단계는 다음과 같다:
-
output을 "erf", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
exp(input, options) 메서드
단계는 다음과 같다:
-
output을 "exp", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
floor(input, options) 메서드
단계는 다음과 같다:
-
output을 "floor", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
identity(input, options)
메서드 단계는 다음과 같다:
-
output을 "identity" input 및 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다.
-
output을 반환한다.
log(input, options) 메서드
단계는 다음과 같다:
-
output을 "log", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
neg(input, options) 메서드
단계는 다음과 같다:
reciprocal(input, options)
메서드 단계는 다음과 같다:
-
output을 "reciprocal", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
roundEven(input, options)
메서드 단계는 다음과 같다:
-
output을 "roundEven", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
sin(input, options) 메서드
단계는 다음과 같다:
-
output을 "sin", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
sign(input, options) 메서드
단계는 다음과 같다:
sqrt(input, options) 메서드
단계는 다음과 같다:
-
output을 "sqrt", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
tan(input, options) 메서드
단계는 다음과 같다:
-
output을 "tan", input, «
"float32","float16"», 그리고 options가 주어졌을 때 element-wise unary operation 만들기의 결과로 둔다. -
output을 반환한다.
sign()
operation의 동작은 일반적으로 다른 operation의 사용을 통해 다음과 같이 에뮬레이션할 수 있지만,
user agent는 보통 더 효율적인 구현을 가진다. 하위 플랫폼이 operation을 직접 지원하지 않는
경우, 이 분해는 구현을 안내하는 템플릿으로 사용할 수 있다.
function sign( builder, input, options) { const zero= builder. constant( input. dataType, 0 ); const positiveOne= builder. constant( input. dataType, 1 ); const negativeOne= builder. constant( input. dataType, - 1 ); return builder. where( builder. greater( input, zero), positiveOne, builder. where( builder. lesser( input, zero), negativeOne, zero)); }
8.9.16. dequantizeLinear
scale 및 zero-point bias를 사용하여 integer tensor를 floating point tensor로 dequantize하며, 여기서output = (input - zeroPoint) * scale이다. scale
및 zeroPoint
tensor들은 blockwise
broadcastable이므로 input
tensor보다 작을 수 있다.
partial interface MLGraphBuilder {MLOperand dequantizeLinear (MLOperand input ,MLOperand scale ,MLOperand zeroPoint ,optional MLOperatorOptions options = {}); };dictionary {MLQuantizeDequantizeLinearSupportLimits MLTensorLimits input ;MLTensorLimits scale ;MLTensorLimits zeroPoint ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLQuantizeDequantizeLinearSupportLimits dequantizeLinear ; };
-
input:MLOperand. 입력 tensor. -
scale:MLOperand. zero point로 조정한 뒤 각 input 값에 곱할 scale tensor. 이는 input과 blockwise broadcastable이어야 한다. 값들은 양수이고 0이 아니어야 하며, 그렇지 않으면 동작은 구현 정의이다(예: 올바른 결과, 잘못된 결과 또는 컴파일 실패). -
zeroPoint:MLOperand. 각 input 값에서 뺄 zero point tensor. 이는 scale과 같은 shape를 가진다. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
dequantize된 값을 포함하는 출력 tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "uint8",
"int8",
"uint32",
"int32"
| "uint8",
"int8"
| N | 0부터 5까지 |
scale
| "float32",
"float16"
| "float32",
"float16"
| input과
동일
| 0부터 5까지 |
zeroPoint
| input과
동일
| "uint8",
"int8",
"int32"
| input과
동일
| 0부터 5까지 |
| output | scale과
동일
| "float32",
"float16"
| input과
동일
| 0부터 5까지 |
MLQuantizeDequantizeLinearSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. scale, 타입은 MLTensorLimits-
scale 피연산자에 대한
MLTensorLimits. zeroPoint, 타입은 MLTensorLimits-
zeroPoint 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
dequantizeLinear()에
대해 다음 멤버를 가진다.
dequantizeLinear, 타입은 MLQuantizeDequantizeLinearSupportLimits-
dequantizeLinear()오퍼레이터에 대한 지원 제한.
dequantizeLinear(input, scale, zeroPoint, options)
메서드 단계는 다음과 같다:
-
this.
[[hasBuilt]]가 true이면, "InvalidStateError"DOMException을 throw한다. -
this와 input, scale, 그리고 zeroPoint 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
scale의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
zeroPoint의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
zeroPoint의 dataType이 input의 dataType과 같지 않으면,
TypeError를 throw한다. -
scale의 rank 또는 zeroPoint의 rank가 input의 rank와 같지 않으면,
TypeError를 throw한다. -
scale의 shape와 input의 shape를 blockwise broadcasting한 결과가 false를 반환하면,
TypeError를 throw한다. -
zeroPoint의 shape와 input의 shape를 blockwise broadcasting한 결과가 false를 반환하면,
TypeError를 throw한다. -
outputDescriptor를 scale의 dataType과 input의 shape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 outputDescriptor가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 input, scale, zeroPoint, 그리고 options가 주어진 "dequantizeLinear" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function dequantizeLinear( builder, input, scale, zeroPoint, options) { // output = (input - zeroPoint) * scale const floatInput= builder. cast( input, scale. dataType); const floatZeroPoint= builder. cast( zeroPoint, scale. dataType); const upsampledScale= blockwiseExpand( builder, scale, input. shape); const upsampledZeroPoint= blockwiseExpand( builder, floatZeroPoint, input. shape); return builder. mul( builder. sub( floatInput, upsampledZeroPoint), upsampledScale); } function blockwiseExpand( builder, input, outputShape) { // 원래 input과 원하는 output shape가 주어지면, 이 함수는 각 axis를 // 해당 axis별 반복 횟수만큼 block을 반복하여 확장한다. 다만 backend // 구현은 모든 dimension을 한 번에 upsample하기 위해 여러 dimension을 // 허용할 수 있는, 훨씬 더 효율적인 upsampling operator를 가질 수 있다. // nearest neighbor resampling을 사용하는 integer multiple 방식이다: // output = resample(scale, {sizes: input.shape}) let output= input; for ( let axis= 0 ; axis< input. shape. length; ++ axis) { const oldShape= output. shape; const oldDimensionLength= oldShape[ axis]; const newDimensionLength= outputShape[ axis]; if ( newDimensionLength!= oldDimensionLength) { // tile/expand는 전체 dimension slice의 반복만 허용하고 // axis를 따라 개별 element를 반복할 수 없으므로, element를 // 전체 block size까지 broadcast할 수 있게 tensor를 일시적으로 // reshape한다. 이때 size 1인 dimension을 삽입한다. const elementRepeatCount= newDimensionLength/ oldDimensionLength; const flattenedShape= getFlattenedShapeAroundAxis( oldShape, axis); const unexpandedShape= [ flattenedShape[ 0 ], flattenedShape[ 1 ], 1 , flattenedShape[ 2 ]]; const expandedShape= [ flattenedShape[ 0 ], flattenedShape[ 1 ], elementRepeatCount, flattenedShape[ 2 ] ]; const reshapedInput= builder. reshape( output, unexpandedShape); output= builder. expand( reshapedInput, expandedShape); let newShape= [... oldShape]; newShape[ axis] = newDimensionLength; output= builder. reshape( output, newShape); } } return output; } // 주어진 axis 전후의 flattened shape를 계산하여 // 3-element list를 산출한다. 예: // - inputShape = [2,3,4,5,6] with axis = 2 yields shape [6,4,30]. // - inputShape = [4] with axis = 0 yields shape [1,4,1]. function getFlattenedShapeAroundAxis( inputShape, axis) { axis= Math. max( Math. min( axis, inputShape. length- 1 ), 0 ); const shapeBefore= inputShape. slice( 0 , axis); const shapeAfter= inputShape. slice( axis+ 1 , inputShape. length); const countBefore= shapeBefore. reduce(( a, b) => a* b, 1 ); const countAfter= shapeAfter. reduce(( a, b) => a* b, 1 ); return [ countBefore, inputShape[ axis], countAfter]; }
8.9.17. quantizeLinear
scale 및 zero-point bias를 사용하여 floating point tensor를 integer tensor로 quantize한다(예: "uint8"의 경우output = clamp(roundEven(input / scale) + zeroPoint, 0, 255)). scale 및
zeroPoint tensor들은 blockwise broadcast되므로
input tensor보다 작을 수 있다.
partial interface MLGraphBuilder {MLOperand quantizeLinear (MLOperand input ,MLOperand scale ,MLOperand zeroPoint ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLQuantizeDequantizeLinearSupportLimits quantizeLinear ; };
-
input:MLOperand. 입력 tensor. -
scale:MLOperand. zero point로 조정하기 전에 각 input 값을 나눌 scale tensor. 이는 input과 blockwise broadcastable이어야 한다. 값들은 양수이고 0이 아니어야 하며, 그렇지 않으면 동작은 구현 의존적이다(예: 올바른 결과, 잘못된 결과 또는 컴파일 실패). -
zeroPoint:MLOperand. rescale된 각 input 값에 더할 zero point tensor. 이는 scale과 같은 shape를 가진다. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
quantize된 값을 포함하는 출력 tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
scale
| 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
zeroPoint
| "uint8",
"int8",
"uint32",
"int32"
| "uint8",
"int8"
| 동일 input
| 0부터 5까지 |
| output | 동일 zeroPoint
| "uint8",
"int8"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
quantizeLinear()에
대해 다음 멤버가 있다:
quantizeLinear, 타입은 MLQuantizeDequantizeLinearSupportLimits-
quantizeLinear()operator에 대한 지원 제한.
quantizeLinear(input, scale, zeroPoint, options)
메서드 단계는 다음과 같다:
-
this.
[[hasBuilt]]가 true이면, "InvalidStateError"DOMException을 throw한다. -
this와 input, scale, 그리고 zeroPoint 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
scale의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
scale의 dataType이 input의 dataType과 같지 않으면,
TypeError를 throw한다. -
zeroPoint의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
scale의 rank 또는 zeroPoint의 rank가 input의 rank와 같지 않으면,
TypeError를 throw한다. -
scale의 shape와 input의 shape를 blockwise broadcasting한 결과가 false를 반환하면,
TypeError를 throw한다. -
zeroPoint의 shape와 input의 shape를 blockwise broadcasting한 결과가 false를 반환하면,
TypeError를 throw한다. -
outputDescriptor를 zeroPoint의 dataType과 input의 shape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 outputDescriptor가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 input, scale, zeroPoint, 그리고 options가 주어진 "quantizeLinear" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function quantizeLinear( builder, input, scale, zeroPoint, options) { // output = clamp(roundEven(input / scale) + zeroPoint, 0, 255) // blockwiseExpand는 dequantizeLinear에서 정의된다. const floatZeroPoint= builder. cast( zeroPoint, scale. dataType); const upsampledScale= blockwiseExpand( builder, scale, input. shape); const upsampledZeroPoint= blockwiseExpand( builder, floatZeroPoint, input. shape); const quantizedInput= builder. roundEven( builder. div( input, upsampledScale)); const zeroPointAdjustedInput= builder. add( quantizedInput, upsampledZeroPoint); const clampedInput= builder. clamp( zeroPointAdjustedInput, { 'minValue' : 0 , 'maxValue' : 255 }); return builder. cast( clampedInput, zeroPoint. dataType); }
8.9.18. elu
input tensor에 대해 exponential linear unit function(ELU)을 element-wise로 계산한다. 계산은max(0, x) + alpha * (exp(min(0, x)) - 1) 표현식을 따른다.
dictionary :MLEluOptions MLOperatorOptions {double alpha = 1; };partial interface MLGraphBuilder {MLOperand elu (MLOperand input ,optional MLEluOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits elu ; };
MLEluOptions는
다음 멤버를 가진다.
alpha, 타입은 double, 기본값은1-
scalar multiplier.
-
input:MLOperand. 입력 tensor. -
options: 선택적MLEluOptions. 연산의 선택적 매개변수.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
elu()에
대해 다음 멤버가 있다:
elu, 타입은 MLSingleInputSupportLimits-
elu()operator에 대한 지원 제한.
elu(input, options) 메서드
단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "elu" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function elu( builder, input, options) { return builder. add( builder. max( builder. constant( input. dataType, 0 ), input), builder. mul( builder. constant( input. dataType, options. alpha), builder. sub( builder. exp( builder. min( builder. constant( input. dataType, 0 ), input)), builder. constant( input. dataType, 1 )))); }
8.9.19. expand
input tensor의 size가 1인 임의의 dimension을 새 shape에 따라 더 큰 size로 확장한다. 이 확장은 [numpy-broadcasting-rule]와 일치한다. input tensor는 새 shape로 unidirectionally broadcastable이어야 한다. 각 dimension은 size가 1이거나 새 shape에 따른 해당 output dimension의 size와 일치해야 한다.partial interface MLGraphBuilder {MLOperand expand (MLOperand input ,sequence <[EnforceRange ]unsigned long >newShape ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits expand ; };
-
input:MLOperand. 입력 tensor -
newShape: sequence<unsigned long>. input tensor가 확장될 새 shape. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
확장된 size shape를 가진 tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
MLOpSupportLimits는
expand()에
대해 다음 멤버를 가진다.
expand, 타입은 MLSingleInputSupportLimits-
expand()오퍼레이터에 대한 지원 제한.
expand(input, newShape, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
outputShape를 input의 shape와 newShape를 unidirectionally broadcasting한 결과로 둔다.
-
outputShape의 size가 (이 표에 따른) output tensor의 허용되는 rank가 아니면,
TypeError를 throw한다. -
outputDescriptor를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 outputDescriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, newShape, 및 options가 주어진 "expand" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.20. gather
indices에 따라 axis를 따라 input tensor의 값들을 gather한다.dictionary :MLGatherOptions MLOperatorOptions { [EnforceRange ]unsigned long axis = 0; };partial interface MLGraphBuilder {MLOperand gather (MLOperand input ,MLOperand indices ,optional MLGatherOptions options = {}); };dictionary {MLGatherSupportLimits MLTensorLimits input ;MLTensorLimits indices ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLGatherSupportLimits gather ; };
MLGatherOptions는
다음 멤버를 가진다.
axis, 타입은 unsigned long, 기본값은0-
gather된 값들이 얻어지는 axis. 그 값은 N이 input tensor의 rank일 때 [0, N-1] 범위 안에 있어야 한다.
-
input:MLOperand. 값을 gather할 input N-D tensor. -
indices:MLOperand. gather할 input 값의 indices N-D tensor. 값은"int32","uint32", 또는"int64"타입이어야 하며,axis가 index하는 input dimension의 size를 N이라고 할 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 하고, 음수 index는 dimension의 끝에서부터 indexing한다는 뜻이다. -
options: optionalMLGatherOptions. operation의 optional parameters.
반환: MLOperand.
input의
rank + indices의
rank
- 1과 같은 rank를
가지는 출력 N-D tensor.
indices
매개변수는 input이 실행 전까지 알려지지 않으므로 graph가 build될 때 gather()에
대해 허용 범위로 clamp될 수 없다. 지정된 clamping 동작이 기반 플랫폼에서 제공되지 않으면, 구현은
컴파일된 graph 안에 clamp()를
도입할 수 있다. 마찬가지로, 기반 플랫폼이 negative indices를 지원하지 않으면, 구현은 dimension의
끝에서부터의 negative index를 positive index로 변환하는 연산들을 컴파일된 graph 안에 도입할 수 있다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32",
"int8",
"uint8"
| 1부터 N까지 | 1부터 5까지 |
indices
| "int32",
"uint32",
"int64"
| "int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32",
"int8",
"uint8"
| 1부터 N까지 | 1부터 5까지 |
MLGatherSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. indices, 타입은 MLTensorLimits-
indices 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
gather()에
대해 다음 멤버를 가진다.
gather, 타입은 MLGatherSupportLimits-
gather()오퍼레이터에 대한 지원 제한.
gather(input, indices, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input 또는 indices 중 어느 하나가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
indicesShape를 indices의 shape로 둔다.
-
axis를 options.
axis로 둔다. -
dimCount를 0으로 둔다.
-
outputRank를 0으로 둔다.
-
outputShape를 빈 list로 둔다.
-
inputShape의 각 size에 대해 반복한다:
-
dimCount가 axis와 같으면, break한다.
-
outputShape[dimCount]를 size로 설정한다.
-
dimCount를 1 증가시킨다.
-
-
outputRank를 dimCount로 설정한다.
-
dimCount를 0으로 둔다.
-
indicesShape의 각 size에 대해 반복한다:
-
outputShape[outputRank + dimCount]를 size로 설정한다.
-
dimCount를 1 증가시킨다.
-
-
outputRank를 outputRank + dimCount로 설정한다.
-
dimCount를 0으로 둔다.
-
inputShape의 각 size에 대해 반복한다:
-
dimCount가 axis보다 작거나 같으면, continue한다.
-
outputShape[outputRank + dimCount - axis - 1]를 size로 설정한다.
-
dimCount를 1 증가시킨다.
-
-
desc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, indices, 및 options가 주어진 "gather" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 indices로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
gather가 서로 다른 slicing scheme에서 어떻게 동작하는지에 대한 예.
// shape [4,3]인 input: // [[ 0, 1, 2], // [10, 11, 12], // [20, 21, 22], // [30, 31, 32]] const input= builder. constant( { dataType: 'float32' , shape: [ 4 , 3 ]}, new Float32Array([ 0 , 1 , 2 , 10 , 11 , 12 , 20 , 21 , 22 , 30 , 31 , 32 ])); // axis = 0 (default) // shape [2]인 indices: // [3,1] // shape [2,3]인 output: // [[30, 31, 32], // [10, 11, 12]] const indices1= builder. constant({ dataType: 'uint32' , shape: [ 2 ]}, new Uint32Array([ 3 , 1 ])); const output1= builder. gather( input, indices1); // axis = 1 // shape [3]인 indices: // [2,1,1] // shape [4,3]인 output: // [[ 2, 1, 1], // [12, 11, 11], // [22, 21, 21], // [32, 31, 31]] const indices2= builder. constant( { dataType: 'uint32' , shape: [ 3 ]}, new Uint32Array([ 2 , 1 , 1 ])); const output2= builder. gather( input, indices2, { axis: 1 }); // axis = 1 // shape [2,2]인 indices: // [[0, 1], // [1, 2]] // shape [4,2,2]인 output: // [[[ 0, 1], [ 1, 2]], // [[10, 11], [11, 12]], // [[20, 21], [21, 22]], // [[30, 31], [31, 32]]] const indices3= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ 0 , 1 , 1 , 2 ])); const output3= builder. gather( input, indices3, { axis: 1 });
8.9.21. gatherElements
indices에 따라 axis를 따라 input tensor의 값들을 gather한다.partial interface MLGraphBuilder {MLOperand gatherElements (MLOperand input ,MLOperand indices ,optional MLGatherOptions options = {}); };partial dictionary MLOpSupportLimits {MLGatherSupportLimits gatherElements ; };
-
input:MLOperand. 값을 gather할 input N-D tensor. -
indices:MLOperand. gather할 input 값의 indices N-D tensor. 값은"int32","uint32", 또는"int64"타입이어야 하며, options.axis가 index하는 input dimension의 size를 N이라고 할 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 하고, 음수 index는 dimension의 끝에서부터 indexing한다는 뜻이다. -
options: optionalMLGatherOptions. operation의 optional parameters.
Returns: MLOperand.
input의
rank와 같은
rank의 output N-D
tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
indices
| "int32",
"uint32",
"int64"
| "int32"
| 동일 input
| 1부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 1부터 5까지 |
MLOpSupportLimits는
gatherElements()에
대해 다음 멤버를 가진다.
gatherElements, 타입은 MLGatherSupportLimits-
gatherElements()오퍼레이터에 대한 지원 제한.
indices
매개변수는 input이 실행 전까지 알려지지 않으므로 graph가 build될 때 gatherElements()에
대해 허용 범위로 clamp될 수 없다. 지정된 clamping 동작이 기반 플랫폼에서 제공되지 않으면, 구현은
컴파일된 graph 안에 clamp()를
도입할 수 있다. 마찬가지로, 기반 플랫폼이 negative indices를 지원하지 않으면, 구현은 dimension의
끝에서부터의 negative index를 positive index로 변환하는 연산들을 컴파일된 graph 안에 도입할 수 있다.
gatherElements(input, indices, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input 및 indices 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input 또는 indices 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
axis를 options.
axis로 둔다. -
indicesShapeExpected를 input의 shape의 복사본으로 둔다.
-
indicesShapeExpected[axis]를 indices의 shape[axis]로 설정한다.
-
indices의 shape가 indicesShapeExpected와 같지 않으면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 input, indices, 그리고 options가 주어진 "gatherElements" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 indices로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
gatherElements가 서로 다른 slicing scheme에서 어떻게 동작하는지에 대한 예.
// shape [4,3]인 input: // [[ 0, 1, 2], // [10, 11, 12], // [20, 21, 22], // [30, 31, 32]] // shape [2,3]인 indices: // [[3, 1, 1], // [2, 0, 3]] // axis = 0 (default) // shape [2,3]인 output: // [[30, 11, 12], // [20, 1, 32]] const input1= builder. constant( { dataType: 'float32' , shape: [ 4 , 3 ]}, new Float32Array([ 0 , 1 , 2 , 10 , 11 , 12 , 20 , 21 , 22 , 30 , 31 , 32 ])); const indices1= builder. constant( { dataType: 'uint32' , shape: [ 2 , 3 ]}, new Uint32Array([ 3 , 1 , 1 , 2 , 0 , 3 ])); const output1= builder. gatherElements( input1, indices1); // shape [4,3]인 input: // [[ 0, 1, 2], // [10, 11, 12], // [20, 21, 22], // [30, 31, 32]] // shape [4,1]인 indices: // [[2], // [1], // [0], // [2]], // axis = 1 // shape [4,1]인 output: // [[ 2], // [11], // [20], // [32]] const indices2= builder. constant( { dataType: 'uint32' , shape: [ 4 , 1 ]}, new Uint32Array([ 2 , 1 , 0 , 2 ])); const output2= builder. gatherElements( input1, indices2, { axis: 1 }); // shape [4,2,2]인 input: // [[[ 0, 1], // [ 10, 11]], // [[100, 101], // [110, 111]], // [[200, 201], // [210, 211]], // [[300, 301], // [310, 311]],] // shape [1,2,2]인 indices: // [[[0, 2], // [1, 3]]], // axis = 0 // shape [1,2,2]인 output: // [[[ 0, 201], // [110, 311]]] const inputData3= new Float32Array( [ 0 , 1 , 10 , 11 , 100 , 101 , 110 , 111 , 200 , 201 , 210 , 211 , 300 , 301 , 310 , 311 ]); const input3= builder. constant({ dataType: 'float32' , shape: [ 4 , 2 , 2 ]}, inputData3); const indices3= builder. constant( { dataType: 'uint32' , shape: [ 1 , 2 , 2 ]}, new Uint32Array([ 0 , 2 , 1 , 3 ])); const output3= builder. gatherElements( input3, indices3, { axis: 0 });
8.9.22. gatherND
indices에 따라 input tensor의 slice들을 gather한다.partial interface MLGraphBuilder {MLOperand gatherND (MLOperand input ,MLOperand indices ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLGatherSupportLimits gatherND ; };
-
input:MLOperand. 값을 gather할 input N-D tensor. -
indices:MLOperand. indices array는 input tensor에 대한 전체 좌표를 포함하며, 가장 오른쪽 dimension은 coordinate마다 dimension 수를 담는다. 따라서 shape가 [10,1]인 indices tensor는 10개의 단일 축 indices를 담고, shape가 [4,3]이면 3D 좌표의 indices 4개를 담는다. 값은"int32","uint32", 또는"int64"타입이어야 하며, 각각 대응하는 input dimension의 size를 N이라고 할 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 하고, 음수 index는 대응하는 dimension의 끝에서부터 indexing한다는 뜻이다. -
options: optionalMLOperatorOptions. operation의 optional parameters.
반환값: MLOperand.
input의
rank + indices의
rank - indices의
shape[-1] - 1과
같은 rank의 output N-D
tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| 임의 | "float32",
"float16",
"int32",
"int8",
"uint8"
| 1부터 N까지 | 1부터 5까지 |
indices
| "int32",
"uint32",
"int64"
| "int32"
| 1부터 N까지 | 1부터 5까지 |
| output | input과
동일
| "float32",
"float16",
"int32",
"int8",
"uint8"
| N | 0부터 5까지 |
MLOpSupportLimits는
gatherND()에
대해 다음 멤버를 가진다.
gatherND, 타입은 MLGatherSupportLimits-
gatherND()오퍼레이터에 대한 지원 제한.
indices
매개변수는 input이 실행 전까지 알려지지 않으므로 graph가 build될 때 gatherND()에
대해 허용 범위로 clamp될 수 없다. 지정된 clamping 동작이 기반 플랫폼에서 제공되지 않으면, 구현은
컴파일된 graph 안에 clamp()를
도입할 수 있다. 마찬가지로, 기반 플랫폼이 negative indices를 지원하지 않으면, 구현은 dimension의
끝에서부터의 negative index를 positive index로 변환하는 연산들을 컴파일된 graph 안에 도입할 수 있다.
gatherND(input, indices, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input 및 indices 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input 또는 indices 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
indicesShape를 indices의 shape로 두고, indicesRank를 indices의 rank로 둔다.
-
input 또는 indices 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
indexableSize를 indicesRank - 1로 둔다.
-
coordinateSize를 indicesShape[indexableSize]로 둔다.
-
outputShape를 빈 list로 둔다.
-
각 index에 대해, 0부터 indexableSize까지(제외)의 범위에서:
-
indicesShape[index]를 outputShape에 추가한다.
-
-
각 index에 대해, coordinateSize부터 inputRank까지(제외)의 범위에서:
-
inputShape[index]를 outputShape에 추가한다.
-
-
outputDesc를 input의 dataType과 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 outputDesc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 input, indices, 그리고 options가 주어진 "gatherND" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 indices로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
gatherND가 서로 다른 slicing scheme에서 어떻게 동작하는지에 대한 예.
// shape [2,2]인 input: // [[0, 1], // [2, 3]] // shape [3,2]인 indices: // [[0, 0], // [1, 1], // [1, 0]] // shape [3]인 output: // [0, 3, 2] const input1= builder. constant( { dataType: 'float32' , shape: [ 2 , 2 ]}, new Float32Array([ 0 , 1 , 2 , 3 ])); const indices1= builder. constant( { dataType: 'uint32' , shape: [ 3 , 2 ]}, new Uint32Array([ 0 , 0 , 1 , 1 , 1 , 0 ])); const output1= builder. gatherND( input1, indices1); // shape [2,2]인 input: // [[0, 1], // [2, 3]] // shape [2,1]인 indices: // [[1], // [0]] // shape [2,2]인 output: // [[2, 3] <= input coordinate [1, *]의 row [2, 3] // [0, 1]] <= input coordinate [0, *]의 row [0, 1] const indices2= builder. constant( { dataType: 'uint32' , shape: [ 2 , 1 ]}, new Uint32Array([ 1 , 0 ])); const output2= builder. gatherND( input1, indices2); // shape [2,2,2]인 input: // [[[0, 1], // [2, 3]], // [[4, 5], // [6, 7]]] // shape [2,2]인 indices: // [[0, 1], // [1, 0]] // shape [2,2]인 output: // [[2, 3], <= input coordinate [0, 1, *]의 row [2, 3] // [4, 5]] <= input coordinate [1, 0, *]의 row [4, 5] const input2= builder. constant( { dataType: 'float32' , shape: [ 2 , 2 , 2 ]}, new Float32Array([ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ])); const indices3= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ 0 , 1 , 1 , 0 ])); const output3= builder. gatherND( input2, indices3); // shape [2,2,2]인 input: // [[[0, 1], // [2, 3]], // [[4, 5], // [6, 7]]] // shape [3,1]인 indices: // [[1], // [0], // [1]] // shape [3,2,2]인 output: // [[[4, 5], <= input coordinate [1, *, *]의 block [[4, 5], [6, 7]] // [6, 7]], // [[0, 1], <= input coordinate [0, *, *]의 block [[0, 1], [2, 3]] // [2, 3]], // [[4, 5], <= input coordinate [1, *, *]의 block [[4, 5], [6, 7]] // [6, 7]]] const indices4= builder. constant( { dataType: 'uint32' , shape: [ 3 , 1 ]}, new Uint32Array([ 1 , 0 , 1 ])); const output4= builder. gatherND( input2, indices4); // shape [2,2,2]인 input: // [[[0, 1], // [2, 3]], // [[4, 5], // [6, 7]]] // shape [5,3]인 indices: // [[0,0,1], // [0,1,0], // [1,0,0], // [1,1,0], // [1,1,1]] // shape [5]인 output: // [1,2,4,6,7] const indices5= builder. constant( { dataType: 'uint32' , shape: [ 5 , 3 ]}, new Uint32Array([ 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 1 ])); const output5= builder. gatherND( input2, indices5);
8.9.23. gelu
input tensor의 gaussian error linear unit function(GELU)을 계산한다. 계산은 다음 표현식을 따른다.0.5 * x * (1 + erf(x / sqrt(2))).
partial interface MLGraphBuilder {MLOperand gelu (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits gelu ; };
-
input:MLOperand. 입력 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
gelu()에
대해 다음 멤버가 있다:
gelu, 타입은 MLSingleInputSupportLimits-
gelu()operator에 대한 지원 제한.
gelu(input, options) 메서드
단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "gelu" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function gelu( builder, input) { return builder. mul( builder. mul( input, builder. constant( input. dataType, 0.5 )), builder. add( builder. constant( input. dataType, 1 ), builder. erf( builder. div( input, builder. sqrt( builder. constant( input. dataType, 2 )))))); }
8.9.24. gemm
Basic Linear Algebra Subprograms의 general matrix multiplication을 계산한다. 계산은alpha * A * B + beta * C 표현식을 따른다. 여기서 A는 shape가 [M, K] 또는
[K, M]인 2-D tensor이고, B는 shape가 [K, N] 또는 [N, K]인
2-D tensor이며, C는 shape [M,
N]로 unidirectionally broadcastable이다. A와
B는 계산 전에 선택적으로 transpose될 수 있다.
dictionary :MLGemmOptions MLOperatorOptions {MLOperand c ;double alpha = 1.0;double beta = 1.0;boolean aTranspose =false ;boolean bTranspose =false ; };partial interface MLGraphBuilder {MLOperand gemm (MLOperand a ,MLOperand b ,optional MLGemmOptions options = {}); };dictionary {MLGemmSupportLimits MLTensorLimits a ;MLTensorLimits b ;MLTensorLimits c ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLGemmSupportLimits gemm ; };
MLGemmOptions는
다음 멤버를 가진다.
c, 타입은 MLOperand-
세 번째 입력 tensor. 이것은 scalar이거나 shape [M, N]로 unidirectionally broadcastable인 shape이다. 지정되지 않으면, 계산은
c가 scalar 0.0인 것처럼 수행된다. alpha, 타입은 double, 기본값은1.0-
첫 번째 입력에 대한 multiplier.
beta, 타입은 double, 기본값은1.0-
세 번째 입력
c에 대한 multiplier. aTranspose, 타입은 boolean, 기본값은false-
output을 계산하기 전에 첫 번째 입력이 transpose되는지를 나타낸다.
bTranspose, 타입은 boolean, 기본값은false-
output을 계산하기 전에 두 번째 입력이 transpose되는지를 나타낸다.
-
a:MLOperand.aTranspose가 false이면 shape [M, K]이고,aTranspose가 true이면 [K, M]인 첫 번째 입력 2-D tensor. -
b:MLOperand.bTranspose가 false이면 shape [K, N]이고,bTranspose가 true이면 [N, K]인 두 번째 입력 2-D tensor. -
options: 선택적MLGemmOptions. 연산의 선택적 매개변수.
반환: MLOperand.
모든 입력의 계산된 product를 포함하는 shape [M, N]의 출력 2-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| "float32",
"float16"
| "float32",
"float16"
| 2 | 2 |
b
| 동일 a
| "float32",
"float16"
| 2 | 2 |
c
| 동일 a
| "float32",
"float16"
| 0부터 2까지 | 0부터 2까지 |
| output | 동일 a
| "float32",
"float16"
| 2 | 2 |
MLGemmSupportLimits에는
다음 멤버가 있다:
a, 타입은 MLTensorLimits-
MLTensorLimits는 a operand에 대한 것이다. b, 타입은 MLTensorLimits-
MLTensorLimits는 b operand에 대한 것이다. c, 타입은 MLTensorLimits-
MLTensorLimits는 c operand에 대한 것이다. output, 타입은 MLTensorLimits-
MLTensorLimits는 output operand에 대한 것이다.
MLOpSupportLimits에는
gemm()에
대해 다음 멤버가 있다:
gemm, 타입은 MLGemmSupportLimits-
gemm()operator에 대한 지원 제한.
gemm(a, b, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 a 및 b 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
a 또는 b 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 a의 dataType으로 casting한 결과로 설정한다. -
options.
beta를 options.beta를 a의 dataType으로 casting한 결과로 설정한다. -
options.
aTranspose가 true이면, shapeA의 item 순서를 뒤집는다. -
options.
bTranspose가 true이면, shapeB의 item 순서를 뒤집는다. -
-
그것이 shape « shapeA[0], shapeB[1] »로 unidirectionally broadcastable하지 않으면,
TypeError를 throw한다. -
그것의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다.
-
-
desc를 a의 dataType과 « shapeA[0], shapeB[1] »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options가 주어진 "gemm" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 a 및 b로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function gemm( builder, a, b, options) { if ( options. aTranspose) a= builder. transpose( a); if ( options. bTranspose) b= builder. transpose( b); let ab= builder. matmul( builder. mul( builder. constant( a. dataType, options. alpha), a), b); return ( options. c? builder. add( ab, builder. mul( builder. constant( a. dataType, options. beta), options. c)) : ab); }
8.9.25. gru
Gated Recurrent Unit [GRU] recurrent network는 update, reset, new gate를 사용하여 network의 temporal sequence 전체에서 output으로 전달되는 output state를 계산한다.enum {MLGruWeightLayout , // update-reset-new gate ordering"zrn" // reset-update-new gate ordering };"rzn" enum {MLRecurrentNetworkActivation ,"relu" ,"sigmoid" };"tanh" enum {MLRecurrentNetworkDirection ,"forward" ,"backward" };"both" dictionary :MLGruOptions MLOperatorOptions {MLOperand bias ;MLOperand recurrentBias ;MLOperand initialHiddenState ;boolean resetAfter =true ;boolean returnSequence =false ;MLRecurrentNetworkDirection direction = "forward";MLGruWeightLayout layout = "zrn";sequence <MLRecurrentNetworkActivation >activations ; };partial interface MLGraphBuilder {sequence <MLOperand >gru (MLOperand input ,MLOperand weight ,MLOperand recurrentWeight , [EnforceRange ]unsigned long steps , [EnforceRange ]unsigned long hiddenSize ,optional MLGruOptions options = {}); };dictionary {MLGruSupportLimits MLTensorLimits input ;MLTensorLimits weight ;MLTensorLimits recurrentWeight ;MLTensorLimits bias ;MLTensorLimits recurrentBias ;MLTensorLimits initialHiddenState ;MLTensorLimits output0 ;MLTensorLimits output1 ; };partial dictionary MLOpSupportLimits {MLGruSupportLimits gru ; };
MLGruOptions는
다음 멤버를 가진다.
bias, 타입은 MLOperand-
shape [numDirections, 3 * hiddenSize]의 2-D 입력 bias tensor. tensor shape의 두 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. recurrentBias, 타입은 MLOperand-
shape [numDirections, 3 * hiddenSize]의 2-D recurrent bias tensor. tensor shape의 두 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. initialHiddenState, 타입은 MLOperand-
shape [numDirections, batchSize, hiddenSize]의 3-D 초기 hidden state tensor. 지정되지 않으면, 구현은 0으로 채워진 tensor를 사용해야 한다.
resetAfter, 타입은 boolean, 기본값은true-
reset gate를 matrix multiplication 뒤에 적용할지 또는 전에 적용할지를 나타낸다.
returnSequence, 타입은 boolean, 기본값은false-
마지막 time step의 output에 더해 각 time step의 모든 output을 담은 전체 sequence도 반환할지 여부를 나타낸다.
direction, 타입은 MLRecurrentNetworkDirection, 기본값은"forward"-
input sequence의 처리 방향.
"both"로 설정되면, weight 및 bias tensor shape의 첫 번째 dimension size는 2여야 하며, input은 양방향으로 처리된다. layout, 타입은 MLGruWeightLayout, 기본값은"zrn"-
GRU의 internal gate, 구체적으로 weight 및 bias tensor shape의 두 번째 dimension에 표시되는
update (z),reset (r),new (n)gate에 대한 weight 및 bias vector의 ordering. activations, 타입은 sequence<MLRecurrentNetworkActivation>-
첫 번째 함수가 update 및 reset gate에 사용되고 두 번째 함수가 new gate에 사용되는 한 쌍의 activation functions를 지정한다. 지정되지 않으면, 각각
"sigmoid"및"tanh"함수가 기본값이다.
-
input:MLOperand. shape [steps, batchSize, inputSize]의 입력 3-D tensor. -
weight:MLOperand. shape [numDirections, 3 * hiddenSize, inputSize]의 3-D input weight tensor. tensor shape의 두 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
recurrentWeight:MLOperand. shape [numDirections, 3 * hiddenSize, hiddenSize]의 3-D recurrent weight tensor. tensor shape의 두 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
steps:unsigned longscalar. recurrent network의 time step 수. 값은 0보다 커야 한다. -
hiddenSize:unsigned longscalar. cell output tensor shape의 세 번째 dimension 값. hidden state feature의 수를 나타낸다. -
options: 선택적MLGruOptions. 연산의 선택적 매개변수.
반환: sequence<MLOperand>.
첫 번째 요소는 network의 마지막 time step의 cell output인 shape
[numDirections, batchSize, hiddenSize]의 3-D tensor이다. 또한 returnSequence가
true로 설정되면, 두 번째 요소는 temporal sequence의 각 time step에서 나온 모든 cell output을 포함하는
shape [steps, numDirections,
batchSize, hiddenSize]의 4-D output tensor이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
| "float32",
"float16"
| "float32",
"float16"
| 3 | 3 |
| 동일
| "float32",
"float16"
| 3 | 3 |
| 동일
| "float32",
"float16"
| 3 | 3 |
bias
| 동일
| "float32",
"float16"
| 2 | 2 |
recurrentBias
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 3 | 3 |
| outputs[0] | 동일
| "float32",
"float16"
| 3 | 3 |
outputs[1] if returnSequence가
true인 경우
| 동일
| "float32",
"float16"
| 4 | 4 |
MLGruSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. weight, 타입은 MLTensorLimits-
weight 피연산자에 대한
MLTensorLimits. recurrentWeight, 타입은 MLTensorLimits-
recurrentWeight 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. recurrentBias, 타입은 MLTensorLimits-
recurrentBias 피연산자에 대한
MLTensorLimits. initialHiddenState, 타입은 MLTensorLimits-
initialHiddenState 피연산자에 대한
MLTensorLimits. output0, 타입은 MLTensorLimits-
모든 output operands[0]에 대한
MLTensorLimits. output1, 타입은 MLTensorLimits-
모든 output operands[1]에 대한
MLTensorLimits.
MLOpSupportLimits는
gru()에
대해 다음 멤버를 가진다.
gru, 타입은 MLGruSupportLimits-
gru()오퍼레이터에 대한 지원 제한.
gru(input, weight, recurrentWeight, steps, hiddenSize, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, weight, recurrentWeight, options.
bias(존재하는 경우), options.recurrentBias(존재하는 경우), 그리고 options.(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input, weight 또는 recurrentWeight 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input, weight 또는 recurrentWeight 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
batchSize를 input의 shape[1]로 둔다.
-
inputSize를 input의 shape[2]로 둔다.
-
numDirections를 options.
direction이"both"이면 2로, 그렇지 않으면 1로 둔다. -
weight의 shape가 « numDirections, 3 * hiddenSize, inputSize »와 같지 않으면,
TypeError를 throw한다. -
recurrentWeight의 shape가 « numDirections, 3 * hiddenSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenSize * 6이 유효한 차원이 아니면,
TypeError를 throw한다.왜 hiddenSize * 6인가?
일부 하위 플랫폼은bias와recurrentBias를 연결한 단일 bias tensor에서 동작한다. 따라서 3 * hiddenSize + 3 * hiddenSize 역시 유효한 차원이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
output shape 계산하기:
-
desc0를 input의 dataType과 « numDirections, batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
options.
returnSequence가 true이면:-
desc1를 input의 dataType 과 « steps, numDirections, batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
-
-
graph 연결 만들기:
-
operator를 weight, recurrentWeight, steps, hiddenSize 및 options가 주어진 "gru" operation의 operator로 둔다.
-
output0를 this와 desc0가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
options.
returnSequence가 true이면:-
output1를 this 와 desc1가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
output을 list « output0, output1 »로 둔다.
-
output0.
[[operator]]및 output1.[[operator]]를 operator로 설정한다.
-
-
그렇지 않으면:
-
output을 list « output0 »로 둔다.
-
output0.
[[operator]]를 operator로 설정한다.
-
-
operator의 inputs를 input, weight, 그리고 recurrentWeight로 설정한다.
-
options.
recurrentBias가 존재하면, 그것을 operator의 inputs에 추가한다. -
operator의 activation functions를 activations의 clone으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
squeeze() helper를 사용하면, 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function gru( builder, input, weight, recurrentWeight, steps, hiddenSize, options) { const batchSize= input. shape[ 1 ]; const inputSize= input. shape[ 2 ]; const direction= options. direction|| 'forward' ; const numDirections= ( direction== 'both' ? 2 : 1 ); let hiddenState= options. initialHiddenState; if ( ! hiddenState) { const desc= { dataType: 'float32' , shape: [ numDirections, batchSize, hiddenSize] }; const totalSize= numDirections* batchSize* hiddenSize; hiddenState= builder. constant( desc, new Float32Array( totalSize). fill( 0 )); } let currentWeight= []; let currentRecurrentWeight= []; let currentBias= []; let currentRecurrentBias= []; let forwardSequence= null ; let backwardSequence= null ; let outputHidden= null ; for ( let dir= 0 ; dir< numDirections; ++ dir) { currentWeight. push( squeeze( builder, builder. slice( weight, [ dir, 0 , 0 ], [ 1 , 3 * hiddenSize, inputSize]))); currentRecurrentWeight. push( squeeze( builder, builder. slice( recurrentWeight, [ dir, 0 , 0 ], [ 1 , 3 * hiddenSize, hiddenSize]))); currentBias. push( options. bias? ( squeeze( builder, builder. slice( options. bias, [ dir, 0 ], [ 1 , 3 * hiddenSize]))) : null ); currentRecurrentBias. push( options. recurrentBias? ( squeeze( builder, builder. slice( options. recurrentBias, [ dir, 0 ], [ 1 , 3 * hiddenSize]))) : null ); let currentHidden= squeeze( builder, builder. slice( hiddenState, [ dir, 0 , 0 ], [ 1 , batchSize, hiddenSize]), [ 0 ]); for ( let step= 0 ; step< steps; ++ step) { const slice= ( dir== 1 || direction== 'backward' ? steps- step- 1 : step); const currentInput= squeeze( builder, builder. slice( input, [ slice, 0 , 0 ], [ 1 , batchSize, inputSize]), [ 0 ]); currentHidden= builder. gruCell( currentInput, currentWeight[ dir], currentRecurrentWeight[ dir], currentHidden, hiddenSize, { bias: currentBias[ dir], recurrentBias: currentRecurrentBias[ dir], resetAfter: options. resetAfter, layout: options. layout, activations: options. activations}); if ( options. returnSequence) { // Expand currentHidden of 2D([batchSize, hiddenSize]) // to 4D([steps, numDirections, batchSize, hiddenSize]) const expandedHiddenAs4D= builder. reshape( currentHidden, [ 1 , 1 , batchSize, hiddenSize]); if ( direction== 'forward' || ( dir== 0 && direction== 'both' )) { forwardSequence= forwardSequence? builder. concat([ forwardSequence, expandedHiddenAs4D], 0 ) : expandedHiddenAs4D; } else if ( direction== 'backward' || ( dir== 1 && direction== 'both' )) { backwardSequence= backwardSequence? builder. concat([ expandedHiddenAs4D, backwardSequence], 0 ) : expandedHiddenAs4D; } } } // Expand currentHidden of 2D([batchSize, hiddenSize]) // to 3D([numDirections, batchSize, hiddenSize]) const expandedHiddenAs3D= builder. reshape( currentHidden, [ 1 , batchSize, hiddenSize]); outputHidden= outputHidden? builder. concat([ outputHidden, expandedHiddenAs3D], 0 ) : expandedHiddenAs3D; } if ( options. returnSequence) { let outputSequence= null ; if ( direction== 'forward' ) { outputSequence= forwardSequence; } else if ( direction== 'backward' ) { outputSequence= backwardSequence; } else if ( direction== 'both' ) { // Concat along axis 1 (numDirections dimension) outputSequence= builder. concat([ forwardSequence, backwardSequence], 1 ); } return [ outputHidden, outputSequence]; } else { return [ outputHidden]; } }
8.9.26. gruCell
Gated Recurrent Unit [GRU] recurrent network의 단일 time step으로, update gate와 reset gate를 사용하여 recurrent network의 temporal sequence 전체에서 output으로 전달되는 hidden state를 계산한다.dictionary :MLGruCellOptions MLOperatorOptions {MLOperand bias ;MLOperand recurrentBias ;boolean resetAfter =true ;MLGruWeightLayout layout = "zrn";sequence <MLRecurrentNetworkActivation >activations ; };partial interface MLGraphBuilder {MLOperand gruCell (MLOperand input ,MLOperand weight ,MLOperand recurrentWeight ,MLOperand hiddenState , [EnforceRange ]unsigned long hiddenSize ,optional MLGruCellOptions options = {}); };dictionary {MLGruCellSupportLimits MLTensorLimits input ;MLTensorLimits weight ;MLTensorLimits recurrentWeight ;MLTensorLimits hiddenState ;MLTensorLimits bias ;MLTensorLimits recurrentBias ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLGruCellSupportLimits gruCell ; };
MLGruCellOptions는
다음 멤버를 가진다.
bias, 타입은 MLOperand-
shape [3 * hiddenSize]의 1-D 입력 bias tensor. tensor shape의 두 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. recurrentBias, 타입은 MLOperand-
shape [3 * hiddenSize]의 1-D recurrent bias tensor. tensor shape의 두 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. resetAfter, 타입은 boolean, 기본값은true-
reset gate를 matrix multiplication 뒤에 적용할지 또는 전에 적용할지를 나타낸다.
layout, 타입은 MLGruWeightLayout, 기본값은"zrn"-
GRU의 internal gate, 구체적으로 weight 및 bias tensor shape의 두 번째 dimension에 표시되는
update (z),reset (r),new (n)gate에 대한 weight 및 bias vector의 ordering. activations, 타입은 sequence<MLRecurrentNetworkActivation>-
첫 번째 함수가 update 및 reset gate에 사용되고 두 번째 함수가 new gate에 사용되는 한 쌍의 activation functions를 지정한다. 지정되지 않으면, 각각
"sigmoid"및"tanh"함수가 기본값이다.
-
input:MLOperand. shape [batchSize, inputSize]의 입력 2-D tensor. -
weight:MLOperand. shape [3 * hiddenSize, inputSize]의 2-D input weight tensor. tensor shape의 첫 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
recurrentWeight:MLOperand. shape [3 * hiddenSize, hiddenSize]의 2-D recurrent weight tensor. tensor shape의 첫 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
hiddenState:MLOperand. shape [batchSize, hiddenSize]의 2-D 입력 hidden state tensor. -
hiddenSize:unsigned longscalar. output tensor shape의 두 번째 dimension 값. hidden state의 feature 수를 나타낸다. -
options: 선택적MLGruCellOptions. 연산의 선택적 매개변수.
반환: MLOperand.
recurrent network의 단일 time step의 cell output hidden state인 shape [batchSize, hiddenSize]의
2-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
| "float32",
"float16"
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
bias
| 동일
| "float32",
"float16"
| 1 | 1 |
recurrentBias
| 동일
| "float32",
"float16"
| 1 | 1 |
| output | 동일
| "float32",
"float16"
| 2 | 2 |
MLGruCellSupportLimits는
다음 멤버를 가진다;
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. weight, 타입은 MLTensorLimits-
weight 피연산자에 대한
MLTensorLimits. recurrentWeight, 타입은 MLTensorLimits-
recurrentWeight 피연산자에 대한
MLTensorLimits. hiddenState, 타입은 MLTensorLimits-
hiddenState 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. recurrentBias, 타입은 MLTensorLimits-
recurrentBias 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
gruCell()에
대해 다음 멤버를 가진다.
gruCell, 타입은 MLGruCellSupportLimits-
gruCell()오퍼레이터에 대한 지원 제한.
gruCell(input, weight, recurrentWeight, hiddenState, hiddenSize, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, weight, recurrentWeight, hiddenState, options.
bias(존재하는 경우), 그리고 options.recurrentBias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input, weight, recurrentWeight 또는 hiddenState 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input, weight, recurrentWeight 또는 hiddenState 중 어느 하나의 rank가 (이 표에 따른) 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
batchSize를 input의 shape[0]으로 둔다.
-
inputSize를 input의 shape[1]로 둔다.
-
weight의 shape가 « 3 * hiddenSize, inputSize »와 같지 않으면,
TypeError를 throw한다. -
recurrentWeight의 shape가 « 3 * hiddenSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenState의 shape가 « batchSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenSize * 6이 유효한 차원이 아니면,
TypeError를 throw한다.왜 hiddenSize * 6인가?
일부 하위 플랫폼은bias와recurrentBias를 연결한 단일 bias tensor에서 동작한다. 따라서 3 * hiddenSize + 3 * hiddenSize 역시 유효한 차원이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
desc를 input의 dataType과 « batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 weight, recurrentWeight, hiddenState, hiddenSize 및 options가 주어진 "gruCell" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input, weight, recurrentWeight 및 hiddenState로 설정한다.
-
options.
recurrentBias가 존재하면, 그것을 operator의 inputs에 추가한다. -
operator의 activation functions를 activations의 clone으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
weight layout이 기본 "zrn"
layout이고, update/reset gate와 new gate의 activation functions가 각각 sigmoid()
및 tanh()일
때 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만,
user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우,
이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function gruCell( builder, input, weight, recurrentWeight, hiddenState, hiddenSize, options) { const one= builder. constant( input. dataType, 1 ); const zero= builder. constant( input. dataType, 0 ); const inputSize= input. shape[ 1 ]; // update gate (z) let z= builder. sigmoid( builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ 0 ], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ 0 ], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 0 , 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ 0 , 0 ], [ hiddenSize, hiddenSize])))))); // reset gate (r) let r= builder. sigmoid( builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ hiddenSize], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ hiddenSize, 0 ], [ hiddenSize, hiddenSize])))))); // new gate (n) let n; if ( options. resetAfter) { n= builder. tanh( builder. add( ( options. bias? builder. slice( options. bias, [ 2 * hiddenSize], [ hiddenSize]) : zero), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 2 * hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. mul( r, builder. add( ( options. recurrentBias? builder. slice( options. recurrentBias, [ 2 * hiddenSize], [ hiddenSize]) : zero), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ 2 * hiddenSize, 0 ], [ hiddenSize, hiddenSize])))))))); } else { n= builder. tanh( builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ 2 * hiddenSize], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ 2 * hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 2 * hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. matmul( builder. mul( r, hiddenState), builder. transpose( builder. slice( recurrentWeight, [ 2 * hiddenSize, 0 ], [ hiddenSize, hiddenSize])))))); } // compute the new hidden state return builder. add( builder. mul( z, hiddenState), builder. mul( n, builder. sub( one, z))); }
8.9.27. hardSigmoid
더 빠른 계산을 위해 sigmoid function 대신 사용되는 비평활 hard sigmoid function을 input tensor에 대해 계산한다.dictionary :MLHardSigmoidOptions MLOperatorOptions {double alpha = 0.2;double beta = 0.5; };partial interface MLGraphBuilder {MLOperand hardSigmoid (MLOperand input ,optional MLHardSigmoidOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits hardSigmoid ; };
MLHardSigmoidOptions는
다음 멤버를 가진다.
alpha, 타입은 double, 기본값은0.2-
scalar multiplier.
beta, 타입은 double, 기본값은0.5-
scalar addition.
-
input:MLOperand. 입력 tensor. -
options: 선택적MLHardSigmoidOptions. 연산의 선택적 매개변수.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
hardSigmoid()에
대해 다음 멤버가 있다:
hardSigmoid, 타입은 MLSingleInputSupportLimits-
hardSigmoid()operator에 대한 지원 제한.
hardSigmoid(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
options.
beta를 options.beta를 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "hardSigmoid" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function hardSigmoid( builder, input, options) { return builder. max( builder. min( builder. add( builder. mul( builder. constant( input. dataType, options. alpha), input), builder. constant( input. dataType, options. beta)), builder. constant( input. dataType, 1 )), builder. constant( input. dataType, 0 )); }
8.9.28. hardSwish
[MobileNetV3]에서 도입된 비선형 함수y = x * max(0, min(6, (x + 3))) / 6를 input tensor에 대해 element-wise로
계산한다.
partial interface MLGraphBuilder {MLOperand hardSwish (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits hardSwish ; };
-
input:MLOperand. 입력 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
hardSwish()에
대해 다음 멤버가 있다:
hardSwish, 타입은 MLSingleInputSupportLimits-
hardSwish()operator에 대한 지원 제한.
hardSwish(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "hardSwish" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function hardSwish( builder, input, options) { return builder. div( builder. mul( input, builder. max( builder. constant( input. dataType, 0 ), builder. min( builder. constant( input. dataType, 6 ), builder. add( input, builder. constant( input. dataType, 3 ))))), builder. constant( input. dataType, 6 )); }
8.9.29. instanceNormalization
[Instance-Normalization]을 사용하여 input을 정규화한다.batchNormalization()에서
정규화에 사용되는 mean 및 variance 값이 model을 훈련하는 동안 batch dimension의 모든 sample에 걸쳐
계산되는 것과 달리, instance normalization에서 사용되는 mean 및 variance 값은 batch 안의 각 개별 sample의
각 input feature에 대해 즉시 계산된다.
dictionary :MLInstanceNormalizationOptions MLOperatorOptions {MLOperand scale ;MLOperand bias ;double epsilon = 1e-5;MLInputOperandLayout layout = "nchw"; };partial interface MLGraphBuilder {MLOperand instanceNormalization (MLOperand input ,optional MLInstanceNormalizationOptions options = {}); };dictionary {MLNormalizationSupportLimits MLTensorLimits input ;MLTensorLimits scale ;MLTensorLimits bias ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLNormalizationSupportLimits instanceNormalization ; };
MLInstanceNormalizationOptions는
다음 멤버를 가진다.
scale, 타입은 MLOperand-
size가 channel 수, 즉 input의 feature dimension size와 같은 scaling 값들의 1-D tensor. 예를 들어
inputtensor가"nchw"layout을 가지는 경우, size는input의 shape[1]과 같다. bias, 타입은 MLOperand-
size가 input의 feature dimension size와 같은 bias 값들의 1-D tensor. 예를 들어
inputtensor가"nchw"layout을 가지는 경우, size는input의 shape[1]과 같다. epsilon, 타입은 double, 기본값은1e-5-
0으로 나누기 때문에 발생하는 계산 오류를 방지하기 위한 작은 값.
layout, 타입은 MLInputOperandLayout, 기본값은"nchw"-
input의 layout format.
-
input:MLOperand. 입력 4-D tensor. -
options: 선택적MLInstanceNormalizationOptions. 연산의 선택적 매개변수.
반환: MLOperand.
input과
같은 shape의 instance-normalized 4-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 4 | 4 |
scale
| 동일 input
| "float32",
"float16"
| 1 | 1 |
bias
| 동일 input
| "float32",
"float16"
| 1 | 1 |
| output | 동일 input
| "float32",
"float16"
| 4 | 4 |
MLNormalizationSupportLimits에는
다음 멤버가 있다:
input, 타입은 MLTensorLimits-
MLTensorLimits는 input operand에 대한 것이다. scale, 타입은 MLTensorLimits-
MLTensorLimits는 scale operand에 대한 것이다. bias, 타입은 MLTensorLimits-
MLTensorLimits는 bias operand에 대한 것이다. output, 타입은 MLTensorLimits-
MLTensorLimits는 output operand에 대한 것이다.
MLOpSupportLimits에는
instanceNormalization()에
대해 다음 멤버가 있다:
instanceNormalization, 타입은 MLNormalizationSupportLimits-
instanceNormalization()operator에 대한 지원 제한.
instanceNormalization(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, options.
scale(존재하는 경우), 그리고 options.bias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
epsilon을 options.epsilon을 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "instanceNormalization" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
input tensor가 "nchw"
layout의 4-D일 때 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만,
user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우,
이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function instanceNormalization( builder, input, options) { // The reduction of the mean and variance values happens over the spatial // dimensions of the input e.g. axis 2 and 3 of the input tensor. const reduceOptions= { axes: [ 2 , 3 ], keepDimensions: true }; const mean= builder. reduceMean( input, reduceOptions); const variance= builder. reduceMean( builder. pow( builder. sub( input, mean), builder. constant( input. dataType, 2 )), reduceOptions); // The scale and bias values are applied per input feature // e.g. axis 1 of the input tensor. const shape= [ 1 , input. shape[ 1 ], 1 , 1 ]; return builder. add( builder. mul( builder. reshape( options. scale, shape), builder. div( builder. sub( input, mean), builder. sqrt( builder. add( variance, options. epsilon)))), builder. reshape( options. bias, shape)); }
8.9.30. layerNormalization
[Layer-Normalization]을 사용하여 input을 정규화한다.batchNormalization()에서는
model이 훈련되는 동안 mean 및 variance 값이 batch dimension의 모든 sample에 걸쳐 계산되고, instanceNormalization()에서는
mean 및 variance 값이 batch 안의 각 개별 sample의 각 input feature에 대해 즉시 계산되는 것과 달리,
layer normalization의 mean 및 variance 값은 batch 안의 각 개별 sample의 모든 input feature에 걸쳐
즉시 계산된다.
dictionary :MLLayerNormalizationOptions MLOperatorOptions {MLOperand scale ;MLOperand bias ;sequence <[EnforceRange ]unsigned long >axes ;double epsilon = 1e-5; };partial interface MLGraphBuilder {MLOperand layerNormalization (MLOperand input ,optional MLLayerNormalizationOptions options = {}); };partial dictionary MLOpSupportLimits {MLNormalizationSupportLimits layerNormalization ; };
MLLayerNormalizationOptions는
다음 멤버를 가진다.
scale, 타입은 MLOperand-
axes멤버에 의해 shape가 결정되는 scaling 값들의 N-D tensor. 즉axes의 각 값은 scaling 값을 가지는 input tensor의 dimension을 나타낸다. 예를 들어axes값이 [1,2,3]이면, 이 tensor의 shape는 input dimension 1, 2, 3의 대응하는 size들의 list이다. 이 멤버가 없으면, scaling 값은 1로 간주된다. bias, 타입은 MLOperand-
axes멤버에 의해 shape가 결정되는 bias 값들의 N-D tensor. 즉axes의 각 값은 bias 값을 가지는 input tensor의 dimension을 나타낸다. 예를 들어axes값이 [1,2,3]이면, 이 tensor의 shape는 input dimension 1, 2, 3의 대응하는 size들의 list이다. 이 멤버가 없으면, bias 값은 0으로 간주된다. axes, 타입은sequence<[EnforceRange] unsigned long>-
reduce할 input dimension에 대한 index들. 이 멤버가 없으면, 첫 번째 dimension을 제외한 모든 dimension이 주어진 것처럼 처리된다(예: 4-D input tensor의 경우,
axes= [1,2,3]). 즉 mean 및 variance 값에 대한 reduction은 각 독립 batch에 대해 모든 input feature에 걸쳐 계산된다. 비어 있으면, 어떤 dimension도 reduce되지 않는다. epsilon, 타입은 double, 기본값은1e-5-
0으로 나누기 때문에 발생하는 계산 오류를 방지하기 위한 작은 값.
-
input:MLOperand. 입력 N-D tensor. -
options: 선택적MLLayerNormalizationOptions. 연산의 선택적 매개변수.
반환: MLOperand.
input과
같은 shape의 layer-normalized N-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
scale
| 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
bias
| 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
layerNormalization()에
대해 다음 멤버가 있다:
layerNormalization, 타입은 MLNormalizationSupportLimits-
layerNormalization()operator에 대한 지원 제한.
layerNormalization(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, options.
scale(존재하는 경우), 그리고 options.bias(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
axes가 존재하지 않으면, options.axes를 새 list로 설정한다. 이 list는 input의 rank가 1보다 크면 1부터 input의 rank까지(제외)의 범위이고, 그렇지 않으면 빈 list이다. -
그렇지 않고, options.
axes가 중복 값을 포함하거나, 그 items 중 어느 하나라도 0부터 input의 rank까지(제외)의 범위 안에 없으면,TypeError를 throw한다. -
options.
epsilon을 options.epsilon을 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "layerNormalization" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
axes 매개변수가 [1,2,3]으로 설정된 경우 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function layerNormalization( builder, input, options) { // The reduction of the mean and variance values happens over the spatial // dimensions across all the input features (i.e. all channels) of the input // tensor. const reduceOptions= { axes: [ 1 , 2 , 3 ], keepDimensions: true }; const mean= builder. reduceMean( input, reduceOptions); const variance= builder. reduceMean( builder. pow( builder. sub( input, mean), builder. constant( input. dataType, 2 )), reduceOptions); // The scale and bias tensors are of the shape of the input // specified by the values in the axes parameter (i.e. [1,2,3]). return builder. add( builder. mul( options. scale, builder. div( builder. sub( input, mean), builder. sqrt( builder. add( variance, options. epsilon)))), options. bias); }
8.9.31. leakyRelu
input tensor에 대해 rectified linear function의 leaky version을 element-wise로 계산한다. 계산은max(0, x) + alpha * min(0, x) 식을 따른다.
dictionary :MLLeakyReluOptions MLOperatorOptions {double alpha = 0.01; };partial interface MLGraphBuilder {MLOperand leakyRelu (MLOperand input ,optional MLLeakyReluOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits leakyRelu ; };
MLLeakyReluOptions는
다음 멤버를 가진다:
alpha, 타입은 double, 기본값은0.01-
scalar multiplier.
-
input:MLOperand. 입력 tensor. -
options: 선택적MLLeakyReluOptions. 연산의 선택적 매개변수.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
leakyRelu()에
대해 다음 멤버가 있다:
leakyRelu, 타입은 MLSingleInputSupportLimits-
leakyRelu()operator에 대한 지원 제한.
leakyRelu(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "leakyRelu" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function leakyRelu( builder, input, options) { return builder. add( builder. max( builder. constant( input. dataType, 0 ), input), builder. mul( builder. constant( input. dataType, options. alpha), builder. min( builder. constant( input. dataType, 0 ), input))); }
8.9.32. linear
input tensor에 대해 linear functiony = alpha * x + beta를 계산한다.
dictionary :MLLinearOptions MLOperatorOptions {double alpha = 1;double beta = 0; };partial interface MLGraphBuilder {MLOperand linear (MLOperand input ,optional MLLinearOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits linear ; };
MLLinearOptions는
다음 멤버를 가진다:
alpha, 타입은 double, 기본값은1-
scalar multiplier.
beta, 타입은 double, 기본값은0-
scalar addition.
-
input:MLOperand. 입력 tensor. -
options: 선택적MLLinearOptions. 연산의 선택적 매개변수.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
linear()에
대해 다음 멤버가 있다:
linear, 타입은 MLSingleInputSupportLimits-
linear()operator에 대한 지원 제한.
linear(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
options.
beta를 options.beta를 input의 dataType으로 casting한 결과로 설정한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "linear" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function linear( builder, input, options) { return builder. add( builder. mul( input, builder. constant( input. dataType, options. alpha)), builder. constant( input. dataType, options. beta)); }
8.9.33. lstm
Long Short-Term Memory [LSTM] recurrent network는 input, output, forget 및 cell gate를 사용하여 network의 temporal sequence 전체에서 output으로 전달되는 output state를 계산한다.enum {MLLstmWeightLayout , // input-output-forget-cell gate ordering"iofg" // input-forget-cell-output gate ordering };"ifgo" dictionary :MLLstmOptions MLOperatorOptions {MLOperand bias ;MLOperand recurrentBias ;MLOperand peepholeWeight ;MLOperand initialHiddenState ;MLOperand initialCellState ;boolean returnSequence =false ;MLRecurrentNetworkDirection direction = "forward";MLLstmWeightLayout layout = "iofg";sequence <MLRecurrentNetworkActivation >activations ; };partial interface MLGraphBuilder {sequence <MLOperand >lstm (MLOperand input ,MLOperand weight ,MLOperand recurrentWeight , [EnforceRange ]unsigned long steps , [EnforceRange ]unsigned long hiddenSize ,optional MLLstmOptions options = {}); };dictionary {MLLstmSupportLimits MLTensorLimits input ;MLTensorLimits weight ;MLTensorLimits recurrentWeight ;MLTensorLimits bias ;MLTensorLimits recurrentBias ;MLTensorLimits peepholeWeight ;MLTensorLimits initialHiddenState ;MLTensorLimits initialCellState ;MLTensorLimits output0 ;MLTensorLimits output1 ;MLTensorLimits output2 ; };partial dictionary MLOpSupportLimits {MLLstmSupportLimits lstm ; };
MLLstmOptions는
다음 멤버를 가진다:
bias, 타입은 MLOperand-
shape [numDirections, 4 * hiddenSize]의 2-D input bias tensor. tensor shape의 두 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. recurrentBias, 타입은 MLOperand-
shape [numDirections, 4 * hiddenSize]의 2-D recurrent bias tensor. tensor shape의 첫 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. peepholeWeight, 타입은 MLOperand-
shape [numDirections, 3 * hiddenSize]인 peephole용 2-D weight tensor. weight vector들의 pack ordering은 각각
input (i),output (o), 및forget (f)gate용이다. initialHiddenState, 타입은 MLOperand-
shape [numDirections, batchSize, hiddenSize]의 3-D initial hidden state tensor. 지정되지 않으면, 구현은 0으로 채워진 tensor를 사용해야 한다.
initialCellState, 타입은 MLOperand-
shape [numDirections, batchSize, hiddenSize]의 3-D initial hidden state tensor. 지정되지 않으면, 구현은 0으로 채워진 tensor를 사용해야 한다.
returnSequence, 타입은 boolean, 기본값은false-
마지막 time step의 output 외에도 각 time step의 모든 output을 포함하는 전체 sequence를 함께 반환할지를 나타낸다.
direction, 타입은 MLRecurrentNetworkDirection, 기본값은"forward"-
input sequence의 처리 방향.
"both"로 설정되면, weight 및 bias tensor shape의 첫 번째 dimension size는 2여야 하며, input은 양방향으로 처리된다. layout, 타입은 MLLstmWeightLayout, 기본값은"iofg"-
LSTM의 internal gate, 구체적으로 weight 및 bias tensor shape의 첫 번째 dimension에 표시되는
input (i),output (o),forget (f), 및cell (g)gate에 대한 weight 및 bias vector의 ordering. activations, 타입은 sequence<MLRecurrentNetworkActivation>-
세 개의 activation functions의 list. 첫 번째 것은
input (i),forget (f), 및output (o)gate에 사용되고, 두 번째 것은cell (g)gate에 사용되며, 마지막 것은 output gate의 결과와 결합하여 output hidden state를 형성하기 전에 output cell state를 필터링하는 데 사용된다. 지정되지 않으면 각각"sigmoid","tanh", 및"tanh"함수의 sequence가 기본값이다.
-
input:MLOperand. shape [steps, batchSize, inputSize]의 입력 3-D tensor. -
weight:MLOperand. shape [numDirections, 4 * hiddenSize, inputSize]의 3-D input weight tensor. tensor shape의 두 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
recurrentWeight:MLOperand. shape [numDirections, 4 * hiddenSize, hiddenSize]의 3-D recurrent weight tensor. tensor shape의 두 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
steps:unsigned longscalar. recurrent network의 time step 수. 값은 0보다 커야 한다. -
hiddenSize:unsigned longscalar. cell output tensor shape의 세 번째 dimension 값. hidden state의 feature 수를 나타낸다. -
options: 선택적MLLstmOptions. 연산의 선택적 매개변수.
반환: sequence<MLOperand>.
첫 번째 요소는 shape [numDirections, batchSize, hiddenSize]의 3-D tensor로, network의 마지막
time step에서 나온 output hidden state이다. 두 번째 요소는 shape
[numDirections, batchSize, hiddenSize]의 3-D tensor로, network의 마지막 time step에서 나온
output cell state이다. 추가로, returnSequence가
true로 설정되면, 세 번째 요소는 temporal sequence에서 각 time step의 모든 output을 포함하는 shape
[steps, numDirections, batchSize, hiddenSize]의 4-D output tensor이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
| "float32",
"float16"
| "float32",
"float16"
| 3 | 3 |
| 동일
| "float32",
"float16"
| 3 | 3 |
| 동일
| "float32",
"float16"
| 3 | 3 |
bias
| 동일
| "float32",
"float16"
| 2 | 2 |
recurrentBias
| 동일
| "float32",
"float16"
| 2 | 2 |
peepholeWeight
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 3 | 3 |
initialCellState
| 동일
| "float32",
"float16"
| 3 | 3 |
| outputs[0] | 동일
| "float32",
"float16"
| 3 | 3 |
| outputs[1] | 동일
| "float32",
"float16"
| 3 | 3 |
outputs[2] if returnSequence가
true인 경우
| 동일
| "float32",
"float16"
| 4 | 4 |
MLLstmSupportLimits에는
다음 멤버가 있다:
input, 타입은 MLTensorLimits-
MLTensorLimits는 input operand에 대한 것이다. weight, 타입은 MLTensorLimits-
MLTensorLimits는 weight operand에 대한 것이다. recurrentWeight, 타입은 MLTensorLimits-
MLTensorLimits는 recurrentWeight operand에 대한 것이다. bias, 타입은 MLTensorLimits-
MLTensorLimits는 bias operand에 대한 것이다. recurrentBias, 타입은 MLTensorLimits-
MLTensorLimits는 recurrentBias operand에 대한 것이다. peepholeWeight, 타입은 MLTensorLimits-
MLTensorLimits는 peepholeWeight operand에 대한 것이다. initialHiddenState, 타입은 MLTensorLimits-
MLTensorLimits는 initialHiddenState operand에 대한 것이다. initialCellState, 타입은 MLTensorLimits-
MLTensorLimits는 initialCellState operand에 대한 것이다. output0, 타입은 MLTensorLimits-
MLTensorLimits는 모든 output operands[0]에 대한 것이다. output1, 타입은 MLTensorLimits-
MLTensorLimits는 모든 output operands[1]에 대한 것이다. output2, 타입은 MLTensorLimits-
MLTensorLimits는 모든 output operands[2]에 대한 것이다.
MLOpSupportLimits에는
lstm()에
대해 다음 멤버가 있다:
lstm, 타입은 MLLstmSupportLimits-
lstm()operator에 대한 지원 제한.
lstm(input, weight, recurrentWeight, steps, hiddenSize, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, weight, recurrentWeight, options.
bias(존재하는 경우), options.recurrentBias(존재하는 경우), options.peepholeWeight(존재하는 경우), options.(존재하는 경우), 그리고 options.initialCellState(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
numDirections를 options.
direction이"both"이면 2로, 그렇지 않으면 1로 둔다. -
input, weight 또는 recurrentWeight 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input, weight 또는 recurrentWeight 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
batchSize를 input의 shape[1]로 둔다.
-
inputSize를 input의 shape[2]로 둔다.
-
weight의 shape가 « numDirections, 4 * hiddenSize, inputSize »와 같지 않으면,
TypeError를 throw한다. -
recurrentWeight의 shape가 « numDirections, 4 * hiddenSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenSize * 8이 유효한 차원이 아니면,
TypeError를 throw한다.왜 hiddenSize * 8인가?
일부 하위 플랫폼은bias와recurrentBias를 연결한 단일 bias tensor에서 동작한다. 따라서 4 * hiddenSize + 4 * hiddenSize 역시 유효한 차원이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
peepholeWeight가 존재하면: -
options.
가 존재하면: -
options.
initialCellState가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
output shape 계산하기:
-
desc를 input의 dataType과 « numDirections, batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
options.
returnSequence가 true이면:-
desc2를 input의 dataType 과 « steps, numDirections, batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
-
-
graph 연결 만들기:
-
operator를 weight, recurrentWeight, steps, hiddenSize 및 options가 주어진 "lstm" operation의 operator로 둔다.
-
output0를 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
output1를 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
options.
returnSequence가 true이면:-
output2를 this와 desc2가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
output을 list « output0, output1, output2 »로 둔다.
-
output0.
[[operator]], output1.[[operator]]및 output2.[[operator]]를 operator로 설정한다.
-
-
그렇지 않으면:
-
output을 list « output0, output1 »로 둔다.
-
output0.
[[operator]]및 output1.[[operator]]를 operator로 설정한다.
-
-
operator의 inputs를 input, weight, 그리고 recurrentWeight로 설정한다.
-
options.
recurrentBias가 존재하면, 그것을 operator의 inputs에 추가한다. -
options.
peepholeWeight가 존재하면, 그것을 operator의 inputs에 추가한다. -
options.
initialCellState가 존재하면, 그것을 operator의 inputs에 추가한다. -
operator의 activation functions를 activations의 clone으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
squeeze() helper를 사용하면, 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function lstm( builder, input, weight, recurrentWeight, steps, hiddenSize, options) { const batchSize= input. shape[ 1 ]; const inputSize= input. shape[ 2 ]; const direction= options. direction|| 'forward' ; const numDirections= ( direction== 'both' ? 2 : 1 ); let hiddenState= options. initialHiddenState; let cellState= options. initialCellState; if ( ! hiddenState) { const desc= { dataType: 'float32' , shape: [ numDirections, batchSize, hiddenSize] }; const totalSize= numDirections* batchSize* hiddenSize; hiddenState= builder. constant( desc, new Float32Array( totalSize). fill( 0 )); } if ( ! cellState) { const desc= { dataType: 'float32' , shape: [ numDirections, batchSize, hiddenSize] }; const totalSize= numDirections* batchSize* hiddenSize; cellState= builder. constant( desc, new Float32Array( totalSize). fill( 0 )); } let currentWeight= []; let currentRecurrentWeight= []; let currentBias= []; let currentRecurrentBias= []; let currentPeepholeWeight= []; let forwardSequence= null ; let backwardSequence= null ; let outputHidden= null ; let outputCell= null ; for ( let dir= 0 ; dir< numDirections; ++ dir) { currentWeight. push( squeeze( builder, builder. slice( weight, [ dir, 0 , 0 ], [ 1 , 4 * hiddenSize, inputSize]))); currentRecurrentWeight. push( squeeze( builder, builder. slice( recurrentWeight, [ dir, 0 , 0 ], [ 1 , 4 * hiddenSize, hiddenSize]))); currentBias. push( options. bias? ( squeeze( builder, builder. slice( options. bias, [ dir, 0 ], [ 1 , 4 * hiddenSize]))) : null ); currentRecurrentBias. push( options. recurrentBias? ( squeeze( builder, builder. slice( options. recurrentBias, [ dir, 0 ], [ 1 , 4 * hiddenSize]))) : null ); currentPeepholeWeight. push( options. peepholeWeight? ( squeeze( builder, builder. slice( options. peepholeWeight, [ dir, 0 ], [ 1 , 3 * hiddenSize]))) : null ); let currentHidden= squeeze( builder, builder. slice( hiddenState, [ dir, 0 , 0 ], [ 1 , batchSize, hiddenSize]), [ 0 ]); let currentCell= squeeze( builder, builder. slice( cellState, [ dir, 0 , 0 ], [ 1 , batchSize, hiddenSize]), [ 0 ]); for ( let step= 0 ; step< steps; ++ step) { const slice= ( dir== 1 || direction== 'backward' ? steps- step- 1 : step); const currentInput= squeeze( builder, builder. slice( input, [ slice, 0 , 0 ], [ 1 , batchSize, inputSize]), [ 0 ]); [ currentHidden, currentCell] = builder. lstmCell( currentInput, currentWeight[ dir], currentRecurrentWeight[ dir], currentHidden, currentCell, hiddenSize, { bias: currentBias[ dir], recurrentBias: currentRecurrentBias[ dir], peepholeWeight: currentPeepholeWeight[ dir], layout: options. layout, activations: options. activations}); if ( options. returnSequence) { // Expand currentHidden of 2D([batchSize, hiddenSize]) // to 4D([steps, numDirections, batchSize, hiddenSize]) const expandedHiddenAs4D= builder. reshape( currentHidden, [ 1 , 1 , batchSize, hiddenSize]); if ( direction== 'forward' || ( dir== 0 && direction== 'both' )) { forwardSequence= forwardSequence? builder. concat([ forwardSequence, expandedHiddenAs4D], 0 ) : expandedHiddenAs4D; } else if ( direction== 'backward' || ( dir== 1 && direction== 'both' )) { backwardSequence= backwardSequence? builder. concat([ expandedHiddenAs4D, backwardSequence], 0 ) : expandedHiddenAs4D; } } } // Expand currentHidden of 2D([batchSize, hiddenSize]) // to 3D([numDirections, batchSize, hiddenSize]) const expandedHiddenAs3D= builder. reshape( currentHidden, [ 1 , batchSize, hiddenSize]); outputHidden= outputHidden? builder. concat([ outputHidden, expandedHiddenAs3D], 0 ) : expandedHiddenAs3D; // Expand currentCell of 2D([batchSize, hiddenSize]) // to 3D([numDirections, batchSize, hiddenSize]) const expandedCellAs3D= builder. reshape( currentCell, [ 1 , batchSize, hiddenSize]); outputCell= outputCell? builder. concat([ outputCell, expandedCellAs3D], 0 ) : expandedCellAs3D; } if ( options. returnSequence) { let outputSequence= null ; if ( direction== 'forward' ) { outputSequence= forwardSequence; } else if ( direction== 'backward' ) { outputSequence= backwardSequence; } else if ( direction== 'both' ) { // Concat along axis 1 (numDirections dimension) outputSequence= builder. concat([ forwardSequence, backwardSequence], 1 ); } return [ outputHidden, outputCell, outputSequence]; } else { return [ outputHidden, outputCell]; } }
8.9.34. lstmCell
Long Short-Term Memory [LSTM] recurrent network의 단일 time step으로, cell state와 input, output, forget gate를 사용하여 network의 temporal sequence 전체에서 output으로 전달되는 다음 time step의 cell state 및 hidden state를 계산한다.dictionary :MLLstmCellOptions MLOperatorOptions {MLOperand bias ;MLOperand recurrentBias ;MLOperand peepholeWeight ;MLLstmWeightLayout layout = "iofg";sequence <MLRecurrentNetworkActivation >activations ; };partial interface MLGraphBuilder {sequence <MLOperand >lstmCell (MLOperand input ,MLOperand weight ,MLOperand recurrentWeight ,MLOperand hiddenState ,MLOperand cellState , [EnforceRange ]unsigned long hiddenSize ,optional MLLstmCellOptions options = {}); };dictionary {MLLstmCellSupportLimits MLTensorLimits input ;MLTensorLimits weight ;MLTensorLimits recurrentWeight ;MLTensorLimits hiddenState ;MLTensorLimits cellState ;MLTensorLimits bias ;MLTensorLimits recurrentBias ;MLTensorLimits peepholeWeight ;MLTensorLimits output0 ;MLTensorLimits output1 ; };partial dictionary MLOpSupportLimits {MLLstmCellSupportLimits lstmCell ; };
MLLstmCellOptions는
다음 멤버를 가진다:
bias, 타입은 MLOperand-
shape [4 * hiddenSize]의 1-D input bias tensor. tensor shape의 첫 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. recurrentBias, 타입은 MLOperand-
shape [4 * hiddenSize]의 1-D recurrent bias tensor. tensor shape의 첫 번째 dimension에서 bias vector들의 ordering은
layout에 따라 지정된다. peepholeWeight, 타입은 MLOperand-
shape [3 * hiddenSize]인 peephole용 1-D weight tensor. weight vector들의 pack ordering은 각각
input (i),output (o), 및forget (f)gate용이다. layout, 타입은 MLLstmWeightLayout, 기본값은"iofg"-
LSTM의 internal gate, 구체적으로 weight 및 bias tensor shape의 첫 번째 dimension에 표시되는
input (i),output (o),forget (f), 및cell (g)gate에 대한 weight 및 bias vector의 ordering. activations, 타입은 sequence<MLRecurrentNetworkActivation>-
세 개의 activation functions의 list. 첫 번째 것은
input (i),forget (f), 및output (o)gate에 사용되고, 두 번째 것은cell (g)gate에 사용되며, 마지막 것은 output gate의 결과와 결합하여 output hidden state를 형성하기 전에 output cell state를 필터링하는 데 사용된다. 지정되지 않으면 각각"sigmoid","tanh", 및"tanh"함수의 sequence가 기본값이다.
-
input:MLOperand. shape [batchSize, inputSize]의 입력 2-D tensor. -
weight:MLOperand. shape [4 * hiddenSize, inputSize]의 2-D input weight tensor. tensor shape의 첫 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
recurrentWeight:MLOperand. shape [4 * hiddenSize, hiddenSize]의 2-D recurrent weight tensor. tensor shape의 첫 번째 dimension에서 weight vector들의 ordering은layout에 따라 지정된다. -
hiddenState:MLOperand. shape [batchSize, hiddenSize]의 2-D input hidden state tensor. -
cellState:MLOperand. shape [batchSize, hiddenSize]의 2-D input cell state tensor. -
hiddenSize:unsigned longscalar. output tensor shape의 두 번째 dimension 값. hidden state의 feature 수를 나타낸다. -
options: 선택적MLLstmCellOptions. 연산의 선택적 매개변수.
반환: sequence<MLOperand>.
첫 번째 요소는 recurrent network의 현재 time step의 output hidden state이다. 다음 요소는 output cell state이다.
두 요소 모두 shape [batchSize, hiddenSize]의 2-D tensor이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
| "float32",
"float16"
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
| 동일
| "float32",
"float16"
| 2 | 2 |
bias
| 동일
| "float32",
"float16"
| 1 | 1 |
recurrentBias
| 동일
| "float32",
"float16"
| 1 | 1 |
peepholeWeight
| 동일
| "float32",
"float16"
| 1 | 1 |
| outputs[0] | 동일
| "float32",
"float16"
| 2 | 2 |
| outputs[1] | 동일
| "float32",
"float16"
| 2 | 2 |
MLLstmCellSupportLimits는
다음 멤버를 가진다:
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. weight, 타입은 MLTensorLimits-
weight 피연산자에 대한
MLTensorLimits. recurrentWeight, 타입은 MLTensorLimits-
recurrentWeight 피연산자에 대한
MLTensorLimits. hiddenState, 타입은 MLTensorLimits-
hiddenState 피연산자에 대한
MLTensorLimits. cellState, 타입은 MLTensorLimits-
cellState 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. recurrentBias, 타입은 MLTensorLimits-
recurrentBias 피연산자에 대한
MLTensorLimits. peepholeWeight, 타입은 MLTensorLimits-
peepholeWeight 피연산자에 대한
MLTensorLimits. output0, 타입은 MLTensorLimits-
모든 output operands[0]에 대한
MLTensorLimits. output1, 타입은 MLTensorLimits-
모든 output operands[1]에 대한
MLTensorLimits.
MLOpSupportLimits는
lstmCell()에
대해 다음 멤버를 가진다:
lstmCell, 타입은 MLLstmCellSupportLimits-
lstmCell()오퍼레이터에 대한 지원 제한.
lstmCell(input, weight, recurrentWeight, hiddenState, cellState, hiddenSize, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, weight, recurrentWeight, hiddenState, cellState, options.
bias(존재하는 경우), options.recurrentBias(존재하는 경우), 그리고 options.peepholeWeight(존재하는 경우) 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,TypeError를 throw한다. -
input, weight, recurrentWeight, hiddenState 또는 cellState 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input, weight, recurrentWeight, hiddenState 또는 cellState 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
batchSize를 input의 shape[0]으로 둔다.
-
inputSize를 input의 shape[1]로 둔다.
-
weight의 shape가 « 4 * hiddenSize, inputSize »와 같지 않으면,
TypeError를 throw한다. -
recurrentWeight의 shape가 « 4 * hiddenSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenState의 shape가 « batchSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
cellState의 shape가 « batchSize, hiddenSize »와 같지 않으면,
TypeError를 throw한다. -
hiddenSize * 8이 유효한 차원이 아니면,
TypeError를 throw한다.왜 hiddenSize * 8인가?
일부 하위 플랫폼은bias와recurrentBias를 연결한 단일 bias tensor에서 동작한다. 따라서 4 * hiddenSize + 4 * hiddenSize 역시 유효한 차원이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
peepholeWeight가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
desc를 새
MLOperandDescriptor로 둔다. -
graph 연결 만들기:
-
output0를 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
output1를 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
output을 list « output0, output1 »로 둔다.
-
operator를 weight, recurrentWeight, hiddenState, cellState, hiddenSize 및 options가 주어진 "lstmCell" operation의 operator로 둔다.
-
output0.
[[operator]]및 output1.[[operator]]를 operator로 설정한다. -
operator의 inputs를 input, weight, recurrentWeight, hiddenState 및 cellState로 설정한다.
-
options.
recurrentBias가 존재하면, 그것을 operator의 inputs에 추가한다. -
options.
peepholeWeight가 존재하면, 그것을 operator의 inputs에 추가한다. -
operator의 activation functions를 activations의 clone으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
weight layout이 기본 "iofg"
layout이고, input/forget/output gate 및 cell gate/output hidden state에 대한 cell state filter의
activation
functions가 각각 sigmoid()
및 tanh()인
경우, 이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만,
user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우,
이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function lstmCell( builder, input, weight, recurrentWeight, hiddenState, cellState, hiddenSize, options) { const zero= builder. constant( input. dataType, 0 ); const inputSize= input. shape[ 1 ]; // input gate (i) let i= builder. sigmoid( builder. add( builder. mul( cellState, ( options. peepholeWeight? builder. slice( options. peepholeWeight, [ 0 ], [ hiddenSize]) : zero)), builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ 0 ], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ 0 ], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 0 , 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ 0 , 0 ], [ hiddenSize, hiddenSize]))))))); // forget gate (f) let f= builder. sigmoid( builder. add( builder. mul( cellState, ( options. peepholeWeight? builder. slice( options. peepholeWeight, [ 2 * hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ 2 * hiddenSize], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ 2 * hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 2 * hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ 2 * hiddenSize, 0 ], [ hiddenSize, hiddenSize]))))))); // cell gate (g) let g= builder. tanh( builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ 3 * hiddenSize], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ 3 * hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ 3 * hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ 3 * hiddenSize, 0 ], [ hiddenSize, hiddenSize])))))); // output gate (o) let o= builder. sigmoid( builder. add( builder. mul( cellState, ( options. peepholeWeight? builder. slice( options. peepholeWeight, [ hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. add( ( options. bias? builder. slice( options. bias, [ hiddenSize], [ hiddenSize]) : zero), ( options. recurrentBias? builder. slice( options. recurrentBias, [ hiddenSize], [ hiddenSize]) : zero)), builder. add( builder. matmul( input, builder. transpose( builder. slice( weight, [ hiddenSize, 0 ], [ hiddenSize, inputSize]))), builder. matmul( hiddenState, builder. transpose( builder. slice( recurrentWeight, [ hiddenSize, 0 ], [ hiddenSize, hiddenSize]))))))); // output cell state (ct) let ct= builder. add( builder. mul( f, cellState), builder. mul( i, g)); // output hidden state (ht) let ht= builder. mul( o, builder. tanh( ct)); return [ ht, ct]; }
8.9.35. matmul
두 input tensor의 matrix product를 계산한다.partial interface MLGraphBuilder {MLOperand matmul (MLOperand a ,MLOperand b ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLBinarySupportLimits matmul ; };
-
a:MLOperand. 최소 2-D인 첫 번째 input tensor. -
b:MLOperand. 최소 2-D인 두 번째 input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
두 input tensor의 matrix product를 포함하는 output tensor.
-
a와b가 둘 다 2-dimensional이면, conventional matrix처럼 곱해져 output으로 2-dimensional tensor를 생성한다. -
a또는b중 하나가N-dimensional이고N > 2인 경우, 이는 마지막 두 index에 대응하는 dimension을 가지는 matrix stack으로 취급된다. matrix multiplication은 broadcast되며, 이는 [numpy-broadcasting-rule]에 따른다.a및b의 shape는 마지막 두 dimension을 제외하고 bidirectionally broadcastable이어야 한다. output은 input tensor들의 최대 rank를 rank로 가지는N-dimensional tensor이다. output tensor의 마지막 두 dimension을 제외한 각 dimension에 대해, 그 size는 input tensor들의 해당 dimension에서의 최대 size이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
a
| "float32",
"float16"
| "float32",
"float16"
| 2부터 N까지 | 2부터 5까지 |
b
| 동일 a
| "float32",
"float16"
| 2부터 N까지 | 2부터 5까지 |
| output | 동일 a
| "float32",
"float16"
| 2부터 N까지 | 2부터 5까지 |
MLOpSupportLimits에는
matmul()에
대해 다음 멤버가 있다:
matmul, 타입은 MLBinarySupportLimits-
matmul()operator에 대한 지원 제한.
matmul(a, b, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 a 및 b 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
a 또는 b 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
output shape 계산하기:
-
rankA를 a의 rank로 둔다.
-
rankB를 b의 rank로 둔다.
-
colsA를 shapeA[rankA - 1]로 둔다.
-
rowsA를 shapeA[rankA - 2]로 둔다.
-
colsB를 shapeB[rankB - 1]로 둔다.
-
rowsB를 shapeB[rankB - 2]로 둔다.
-
batchShapeA를 spatial dimensions(마지막 2개 item)가 제거된 shapeA의 clone으로 둔다.
-
batchShapeB를 spatial dimensions(마지막 2개 item)가 제거된 shapeB의 clone으로 둔다.
-
outputShape를 batchShapeA와 batchShapeB를 bidirectionally broadcasting한 결과로 둔다. 이것이 failure를 반환하면,
TypeError를 throw한다. -
« rowsA, colsB »를 outputShape에 append한다.
-
desc를 a의 dataType과 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options가 주어진 "matmul" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 a 및 b로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.36. pad
edge에서 constant 또는 mirrored 값으로 tensor를 확장한다.enum {MLPaddingMode ,"constant" ,"edge" };"reflection" dictionary :MLPadOptions MLOperatorOptions {MLPaddingMode mode = "constant";MLNumber value = 0; };partial interface MLGraphBuilder {MLOperand pad (MLOperand input ,sequence <[EnforceRange ]unsigned long >beginningPadding ,sequence <[EnforceRange ]unsigned long >endingPadding ,optional MLPadOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits pad ; };
MLPadOptions는
다음 멤버를 가진다:
mode, 타입은 MLPaddingMode, 기본값은"constant"-
tensor를 padding하는 여러 방식.
value, 타입은 MLNumber, 기본값은0-
mode가"constant"로 설정된 경우의 padding 값.
-
input:MLOperand. input tensor. -
beginningPadding: sequence<unsigned long>. 각 input dimension의 시작 부분에 추가할 padding 값의 수로, 길이는 N이며 여기서 N은 input tensor의 rank이다.input의 각 dimension d에 대해,beginningPadding[d]는 해당 dimension에서 content 앞에 몇 개의 값을 추가할지를 나타낸다. -
endingPadding: sequence<unsigned long>. 각 input dimension의 끝 부분에 추가할 padding 값의 수로, 길이는 N이며 여기서 N은 input tensor의 rank이다.input의 각 dimension d에 대해,endingPadding[d]는 해당 dimension에서 content 뒤에 몇 개의 값을 추가할지를 나타낸다. -
options: 선택적MLPadOptions. 연산의 선택적 매개변수.
반환: MLOperand.
padding된 output tensor. output tensor의 각 dimension은 다음과 같이 계산할 수 있다:
output size = beginning padding + input size + ending padding
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits는
pad()에
대해 다음 멤버를 가진다:
pad, 타입은 MLSingleInputSupportLimits-
pad()오퍼레이터에 대한 지원 제한.
pad(input, beginningPadding, endingPadding, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
beginningPadding의 size와 endingPadding의 size가 둘 다 input의 rank와 같지 않으면,
TypeError를 throw한다. -
desc를 input.
[[descriptor]]의 copy로 둔다. -
outputShape를 input의 shape의 copy로 둔다.
-
0부터 outputShape의 rank까지의 range에 있는 각 index에 대해 For each, exclusive:
-
options.
mode에 대해 switch한다:"constant"-
아무것도 하지 않는다.
"edge"-
아무것도 하지 않는다.
"reflection"
-
beginningPadding[index]의 값을 outputShape[index]에 더한다.
-
endingPadding[index]의 값을 outputShape[index]에 더한다.
-
-
outputShape의 어떤 item이라도 유효한 dimension이 아니면,
TypeError를 throw한다. -
options.
value를 options.value를 input의 dataType으로 casting한 결과로 설정한다. -
desc.
shape를 outputShape로 설정한다. -
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 beginningPadding, endingPadding 및 options가 주어진 "padding" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
constant, edge, reflection padding 예:
// input: [[1,2,3], [4,5,6]] const input= builder. constant( { dataType: 'float32' , shape: [ 2 , 3 ]}, new Float32Array([ 1 , 2 , 3 , 4 , 5 , 6 ])); const beginningPadding= [ 1 , 2 ]; const endingPadding= [ 1 , 2 ]; // "constant" padding 적용: // [[0,0,0,0,0,0,0], // [0,0,1,2,3,0,0], // [0,0,4,5,6,0,0], // [0,0,0,0,0,0,0]] builder. pad( input, beginningPadding, endingPadding); // "edge" padding 적용: // [[1,1,1,2,3,3,3], // [1,1,1,2,3,3,3], // [4,4,4,5,6,6,6], // [4,4,4,5,6,6,6]] builder. pad( input, beginningPadding, endingPadding, { mode: 'edge' }); // "reflection" padding 적용: // [[6,5,4,5,6,5,4], // [3,2,1,2,3,2,1], // [6,5,4,5,6,5,4], // [3,2,1,2,3,2,1]] builder. pad( input, beginningPadding, endingPadding, { mode: 'reflection' });
8.9.37. Pooling operations
input tensor 위를 이동하는 window 내의 모든 요소에 걸쳐 pooling 연산을 계산한다.enum {MLRoundingType ,"floor" };"ceil" dictionary :MLPool2dOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >windowDimensions ;sequence <[EnforceRange ]unsigned long >padding ;sequence <[EnforceRange ]unsigned long >strides ;sequence <[EnforceRange ]unsigned long >dilations ;MLInputOperandLayout layout = "nchw";MLRoundingType outputShapeRounding = "floor";sequence <[EnforceRange ]unsigned long >outputSizes ; };partial interface MLGraphBuilder {MLOperand averagePool2d (MLOperand input ,optional MLPool2dOptions options = {});MLOperand l2Pool2d (MLOperand input ,optional MLPool2dOptions options = {});MLOperand maxPool2d (MLOperand input ,optional MLPool2dOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits averagePool2d ;MLSingleInputSupportLimits l2Pool2d ;MLSingleInputSupportLimits maxPool2d ; };
MLPool2dOptions는
다음 멤버를 가진다:
windowDimensions, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [windowHeight, windowWidth]. sliding window의 dimensions를 지정한다. window dimensions의 기본값은 input shape의 height 및 width dimensions이다.
padding, 타입은sequence<[EnforceRange] unsigned long>-
길이 4의 list: [beginningHeight, endingHeight, beginningWidth, endingWidth]. convolution input의 각 spatial dimension의 beginning 및 ending에 추가되는 row와 column을 지정한다. 기본값은 [0,0,0,0]이다.
strides, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [strideHeight, strideWidth]. convolution input의 각 spatial dimension에 대한 sliding window의 stride를 지정한다. 기본값은 [1,1]이다.
dilations, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [dilationHeight, dilationWidth]. convolution filter(kernel)에 적용되는 각 spatial dimension의 dilation factor를 지정한다. 기본값은 [1,1]이다.
layout, 타입은 MLInputOperandLayout, 기본값은"nchw"-
input 및 output tensor의 layout format을 다음과 같이 지정한다:
outputShapeRounding, 타입은 MLRoundingType, 기본값은"floor"-
full window 결과를 원하는지 partial window 결과를 원하는지에 따라, output shape를 계산하는 데 사용되는 rounding function.
outputSizes, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list: [outputHeight, outputWidth] output tensor의 두 spatial dimensions의 size를 지정한다. output sizes가 명시적으로 지정되면,
outputShapeRounding은 무시된다. 지정되지 않으면, output sizes는 자동으로 계산된다.
-
input:MLOperand. input 4-D tensor. logical shape는layout의 값에 따라 해석된다. -
options: 선택적MLPool2dOptions. 연산의 선택적 매개변수.
반환: MLOperand.
reduction 결과를 포함하는 output 4-D tensor. logical shape는
layout의
값에 따라 해석된다.
더 구체적으로, outputShapeRounding이
"floor"이면,
output tensor의 단일 dimension에 대한 spatial dimensions는 다음과 같이 계산할 수 있다:
output size = floor(1 + (input size - filter size + beginning padding + ending padding) / stride)
또는 outputShapeRounding이
"ceil"인
경우:
output size = ceil(1 + (input size - filter size + beginning padding + ending padding) / stride)
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 4 | 4 |
| output | 동일 input
| "float32",
"float16"
| 4 | 4 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16"
| 4 | 4 |
| output | 동일 input
| "float32",
"float16"
| 4 | 4 |
MLOpSupportLimits에는
pooling operation에 대해 다음 멤버가 있다:
averagePool2d, 타입은 MLSingleInputSupportLimits-
averagePool2d()operator에 대한 지원 제한. l2Pool2d, 타입은 MLSingleInputSupportLimits-
l2Pool2d()operator에 대한 지원 제한. maxPool2d, 타입은 MLSingleInputSupportLimits-
maxPool2d()operator에 대한 지원 제한.
// 'global' max pooling builder. maxPool2d( input);
string
op, MLOperand
input, MLPool2dOptions
options, 그리고 선택적 list allowedDataTypes가 주어졌을 때, pooling operation 만들기는 다음 단계를 실행한다:
-
Assert: op는 "averagePool2d", "l2Pool2d", "maxPool2d" 중 하나이다.
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
allowedDataTypes가 주어졌고, 그것이 input의 dataType을 포함하지 않으면,
TypeError를 throw한다. -
options.
layout에 대해 switch한다: -
options.
windowDimensions가 존재하지 않으면, options.windowDimensions를 « inputHeight, inputWidth »로 설정한다. -
options.
windowDimensions의 size가 2가 아니면,TypeError를 throw한다. -
options.
windowDimensions의 어느 item이라도 0과 같으면,TypeError를 throw한다. -
options.
outputSizes가 존재하거나, options.padding이 존재하지 않으면, options.padding을 list « 0, 0, 0, 0 »로 설정한다. -
options.
strides가 존재하지 않으면, options.strides를 list « 1, 1 »로 설정한다. -
options.
outputSizes가 존재하면: -
options.
dilations가 존재하지 않으면, options.dilations를 list « 1, 1 »로 설정한다. -
desc를 input.
[[descriptor]]의 복사본으로 둔다. -
output shape 계산하기:
-
« windowHeight, windowWidth »를 options.
windowDimensions로 둔다. -
« calculatedOutputHeight, calculatedOutputWidth »를 inputHeight, inputWidth, windowHeight, windowWidth, options.
padding, options.strides, 그리고 options.dilations가 주어졌을 때 conv2d output sizes 계산하기의 결과로 둔다. -
options.
outputSizes가 존재하면:-
« outputHeight, outputWidth »를 options.
outputSizes로 둔다. -
outputHeight가 floor( calculatedOutputHeight )와 같고 outputWidth가 floor( calculatedOutputWidth )와 같은 경우도 아니고, outputHeight가 ceil( calculatedOutputHeight )와 같고 outputWidth가 ceil( calculatedOutputWidth )와 같은 경우도 아니면,
TypeError를 throw한다.
-
-
그렇지 않으면:
-
« outputHeight, outputWidth »를 « calculatedOutputHeight, calculatedOutputWidth »로 둔다.
-
options.
outputShapeRounding에 대해 switch한다:
-
-
outputHeight 또는 outputWidth 중 어느 하나가 유효한 차원이 아니면,
TypeError를 throw한다. -
options.
layout에 대해 switch한다: -
desc.
shape를 outputShape로 설정한다.
-
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options가 주어진 op operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
다음 pooling 알고리즘이 지원된다.
averagePool2d(input, options)
메서드 단계는 다음과 같다:
-
output을 "averagePool2d", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 pooling operation 만들기의 결과로 둔다. -
output을 반환한다.
l2Pool2d(input, options)
메서드 단계는 다음과 같다:
-
output을 "l2Pool2d", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 pooling operation 만들기의 결과로 둔다. -
output을 반환한다.
maxPool2d(input, options)
메서드 단계는 다음과 같다:
-
output을 "maxPool2d", input 및 options가 주어졌을 때 pooling operation 만들기의 결과로 둔다.
-
output을 반환한다.
8.9.37.1. averagePool2d
feature map의 patch들에 대한 평균값을 계산하고, 이를 사용하여 pooled feature map을 생성한다. 자세한 내용은 § 8.9.37 Pooling operations를 참조하라.8.9.37.2. l2Pool2d
L2 norm 함수를 input feature map의 region에 적용한다. L2 norm은 그 요소들의 제곱 합의 제곱근이다. 자세한 내용은 § 8.9.37 Pooling operations를 참조하라.8.9.37.3. maxPool2d
feature map의 patch들에 대한 최댓값을 계산하고, 이를 사용하여 pooled feature map을 생성한다. 자세한 내용은 § 8.9.37 Pooling operations를 참조하라.8.9.38. prelu
input tensor에 rectified linear function의 parametric version(Parametric ReLU)을 element-wise로 계산한다. Parametric ReLU는 0.01과 같은 scalar slope를 가지는 대신 slope(leakage의 coefficient)를 이 연산의 model training 단계에서 학습되는 parameter로 만드는 leaky ReLU의 한 종류이다. 계산은max(0, x) + slope * min(0, x)
표현식을 따른다.
연산은 broadcast되며, 이는 [numpy-broadcasting-rule]에 따른다. input tensor들은 bidirectionally broadcastable이어야 한다. output tensor의 rank는 input tensor들의 최대 rank이다. output tensor의 각 dimension에 대해, 그 size는 input tensor들의 해당 dimension에서의 최대 size이다.
partial interface MLGraphBuilder {MLOperand prelu (MLOperand input ,MLOperand slope ,optional MLOperatorOptions options = {}); };dictionary {MLPreluSupportLimits MLTensorLimits input ;MLTensorLimits slope ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLPreluSupportLimits prelu ; };
-
input:MLOperand. input tensor. -
slope:MLOperand. slope tensor. 그 shape는input의 shape에 대해 bidirectionally broadcastable이어야 한다. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| "float32",
"float16"
| N | 0부터 5까지 |
slope
| 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
MLPreluSupportLimits에는
다음 멤버가 있다:
input, 타입은 MLTensorLimits-
MLTensorLimits는 input operand에 대한 것이다. slope, 타입은 MLTensorLimits-
MLTensorLimits는 slope operand에 대한 것이다. output, 타입은 MLTensorLimits-
MLTensorLimits는 output operand에 대한 것이다.
MLOpSupportLimits에는
prelu()에
대해 다음 멤버가 있다:
prelu, 타입은 MLPreluSupportLimits-
prelu()operator에 대한 지원 제한.
prelu(input, slope, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input 및 slope 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input 또는 slope 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
outputShape를 slope의 shape와 input의 shape를 bidirectionally broadcasting한 결과로 둔다.
-
descriptor를 input의 dataType과 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 slope와 options가 주어진 "prelu" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input 및 slope로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function prelu( builder, input, slope) { return builder. add( builder. max( builder. constant( input. dataType, 0 ), input), builder. mul( slope, builder. min( builder. constant( input. dataType, 0 ), input))); }
8.9.39. Reduction operations
input tensor를 모든 dimensions를 따라, 또는axes
array parameter에 지정된 axes를 따라 reduce한다. 지정된 각 axis에 대해, 해당 index를 가진 dimension이
reduce된다. 즉, keepDimensions가
지정되지 않는 한 결과 tensor에는 그 dimension이 포함되지 않는다. 결과 tensor의 값은 reduced dimensions 전체에
걸친 모든 input 값을 parameter로 받는 지정된 reduction function을 사용하여 계산된다.
dictionary :MLReduceOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >axes ;boolean keepDimensions =false ; };partial interface MLGraphBuilder {MLOperand reduceL1 (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceL2 (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceLogSum (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceLogSumExp (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceMax (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceMean (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceMin (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceProduct (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceSum (MLOperand input ,optional MLReduceOptions options = {});MLOperand reduceSumSquare (MLOperand input ,optional MLReduceOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits reduceL1 ;MLSingleInputSupportLimits reduceL2 ;MLSingleInputSupportLimits reduceLogSum ;MLSingleInputSupportLimits reduceLogSumExp ;MLSingleInputSupportLimits reduceMax ;MLSingleInputSupportLimits reduceMean ;MLSingleInputSupportLimits reduceMin ;MLSingleInputSupportLimits reduceProduct ;MLSingleInputSupportLimits reduceSum ;MLSingleInputSupportLimits reduceSumSquare ; };
MLReduceOptions는
다음 멤버를 가진다:
axes, 타입은sequence<[EnforceRange] unsigned long>-
reduce할 dimensions로, reduction function에 input tensor의 어떤 값들이 사용되는지도 지정한다. list의 axes는 [0, N-1] 범위 안에 있어야 하며, 여기서 N은 input tensor의 rank이다.
존재하지 않으면 모든 dimensions가 reduce된다. reduction function에 대한 input 값은 input tensor의 모든 값이다.
존재하고 비어 있지 않으면, reduction function에 대한 input 값은 input tensor의 지정된 dimensions에 대한 모든 값이다.
존재하고 비어 있으면, 어떤 dimensions도 reduce되지 않으며 output tensor의 shape는 input tensor의 shape와 같다. reduction function은 tensor의 각 값에 개별적으로 적용된다.
keepDimensions, 타입은 boolean, 기본값은false-
true이면, output은 input과 같은 rank를 가지며, reduce된 모든 dimensions를 size 1로 설정한다.
-
input:MLOperand. input tensor. -
options: 선택적MLReduceOptions. 연산의 선택적 매개변수.
반환: MLOperand.
input의
rank까지 포함하여
0부터 그 rank까지의 범위에 있는 rank를 가지는 output N-D tensor이며, 이는 axes
및 keepDimensions에
따라 달라진다.
input operand가 scalar이면, reduction function은 scalar 값에 적용되고 output도 scalar이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int32",
"uint32",
"int64",
"uint64"
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int32",
"uint32",
"int64",
"uint64"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| N | 0부터 5까지 |
MLOpSupportLimits에는
reduction operation에 대해 다음 멤버가 있다:
reduceL1, 타입은 MLSingleInputSupportLimits-
reduceL1()operator에 대한 지원 제한. reduceL2, 타입은 MLSingleInputSupportLimits-
reduceL2()operator에 대한 지원 제한. reduceLogSum, 타입은 MLSingleInputSupportLimits-
reduceLogSum()operator에 대한 지원 제한. reduceLogSumExp, 타입은 MLSingleInputSupportLimits-
reduceLogSumExp()operator에 대한 지원 제한. reduceMax, 타입은 MLSingleInputSupportLimits-
reduceMax()operator에 대한 지원 제한. reduceMean, 타입은 MLSingleInputSupportLimits-
reduceMean()operator에 대한 지원 제한. reduceMin, 타입은 MLSingleInputSupportLimits-
reduceMin()operator에 대한 지원 제한. reduceProduct, 타입은 MLSingleInputSupportLimits-
reduceProduct()operator에 대한 지원 제한. reduceSum, 타입은 MLSingleInputSupportLimits-
reduceSum()operator에 대한 지원 제한. reduceSumSquare, 타입은 MLSingleInputSupportLimits-
reduceSumSquare()operator에 대한 지원 제한.
-
L1: L1 norm, 즉 input 값들의 절댓값의 합을 계산한다.
-
L2: L2 norm, 즉 input 값들의 제곱의 합의 제곱근을 계산한다.
-
LogSum: input 값들의 합의 log 값을 계산한다.
-
LogSumExp: input 값들의 exponent의 합의 log 값을 계산한다.
-
Max: input 값들의 최댓값을 계산한다.
-
Mean: input 값들의 평균값을 계산한다.
-
Min: input 값들의 최솟값을 계산한다.
-
Product: input 값들의 product를 계산한다.
-
Sum: input 값들의 합을 계산한다.
-
SumSquare: input 값들의 제곱의 합을 계산한다.
unsigned integers의 list inputShape, unsigned integers의 선택적 list axes, 및 boolean keepDimensions가 주어졌을 때 reduction output sizes를 계산하려면, 다음 단계를 수행한다. 이는 unsigned integers의 새 list 또는 failure를 반환한다.
string
op, MLOperand
input, MLReduceOptions
options, 및 선택적 list allowedDataTypes가 주어졌을 때 reduction operation을 생성하려면, 다음 단계를 실행한다:
-
Assert: op는 "reduceL1", "reduceL2", "reduceLogSum", "reduceLogSumExp", "reduceMax", "reduceMean", "reduceMin", "reduceProduct", "reduceSum", "reduceSumSquare" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
allowedDataTypes가 주어졌고 그것이 input의 dataType을 contain하지 않으면,
TypeError를 throw한다. -
outputShape를 input의 shape, options.
axes(그것이 존재하면), 및 options.keepDimensions가 주어졌을 때 reduction output sizes를 계산한 결과로 둔다. 그것이 failure를 반환하면,TypeError를 throw한다. -
desc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
다음 reduction 알고리즘이 지원된다.
reduceL1(input, options)
메서드 단계는 다음과 같다:
reduceL2(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceL2", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 reduction operation 만들기의 결과로 둔다. -
output을 반환한다.
reduceLogSum(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceLogSum", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 reduction operation 만들기의 결과로 둔다. -
output을 반환한다.
reduceLogSumExp(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceLogSumExp", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 reduction operation 만들기의 결과로 둔다. -
output을 반환한다.
reduceMax(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceMax", input 및 options가 주어졌을 때 reduction operation 만들기의 결과로 둔다.
-
output을 반환한다.
reduceMean(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceMean", input, options, 그리고 «
"float32","float16"»가 주어졌을 때 reduction operation 만들기의 결과로 둔다. -
output을 반환한다.
reduceMin(input, options)
메서드 단계는 다음과 같다:
-
output을 "reduceMin", input 및 options가 주어졌을 때 reduction operation 만들기의 결과로 둔다.
-
output을 반환한다.
reduceProduct(input, options)
메서드 단계는 다음과 같다:
reduceSum(input, options)
메서드 단계는 다음과 같다:
여러 reduction operations의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function reduceLogSum( builder, input, options) { return builder. log( builder. reduceSum( input, options)); } function reduceLogSumExp( builder, input, options) { return builder. log( builder. reduceSum( builder. exp( input), options)); } function reduceSumSquare( builder, input, options) { return builder. reduceSum( builder. pow( input, 2 ), options); }
keepDimensions와
같은 option을 직접 지원하지 않는다. 이는 기반 tensor data에는 영향을 주지 않고 shape에만 영향을 준다. 예를 들어,
input shape가 [2, 3, 4]이고, axis가 1이며, keepDimensions가
true이면, 기대되는 output shape는 [2, 1 ,4]이다. 기반 플랫폼이 reduce된 dimensions를 절대 유지하지
않으면, output shape [2, 4]를 생성한다. 구현은 [2, 1, 4]로 no-op reshape를 도입할 수
있다. keepDimensions가
false이지만 기반 플랫폼이 항상 reduce된 dimensions를 유지하는 경우에도 유사한 no-op reshape를 도입할 수 있다.
8.9.40. relu
input tensor의 rectified linear function을 계산한다.partial interface MLGraphBuilder {MLOperand relu (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits relu ; };
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
relu()에
대해 다음 멤버가 있다:
relu, 타입은 MLSingleInputSupportLimits-
relu()operator에 대한 지원 제한.
relu(input, options) 메서드
단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "relu" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
function relu( builder, input) { return builder. max( builder. constant( input. dataType, 0 ), input); }
8.9.41. resample2d
axes 및 scaling factors에 따라 source dimensions에서 destination dimensions로 tensor 값을 resample한다.enum {MLInterpolationMode "nearest-neighbor" ,"linear" };dictionary :MLResample2dOptions MLOperatorOptions {MLInterpolationMode mode = "nearest-neighbor";sequence <float >scales ;sequence <[EnforceRange ]unsigned long >sizes ;sequence <[EnforceRange ]unsigned long >axes ; };partial interface MLGraphBuilder {MLOperand resample2d (MLOperand input ,optional MLResample2dOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits resample2d ; };
-
input:MLOperand. input 4-D tensor. -
options: 선택적MLResample2dOptions. 연산의 선택적 매개변수.
반환: MLOperand.
output 4-D tensor.
MLResample2dOptions는
다음 멤버를 가진다:
mode, 타입은 MLInterpolationMode, 기본값은"nearest-neighbor"-
output tensor 값을 채우는 데 사용되는 interpolation 알고리즘.
두 알고리즘은 각 spatial axis에 대해 계산되는 다음 inputs로 시작한다(
axes에 기반함). 여기서inputSize는inputtensor의 shape로 주어지고,outputSize는sizes또는scales로 주어지며,outputCoordinate는 계산 중인 output tensor의 element를 식별한다.scale = outputSize / inputSize unclampedCoordinate = (outputCoordinate + 0.5) / scale - 0.5 inputCoordinate = clamp(unclampedCoordinate, 0, inputSize - 1)
output tensor에서 주어진outputCoordinate.x및outputCoordinate.y위치에 대해, 위 식은 rationalinputCoordinate.x및inputCoordinate.y를 제공한다.nearest-neighbor-
위에서 계산된
inputCoordinate.x및inputCoordinate.y는 output tensor 값을 다음과 같이 계산하기 위해 nearest-neighbor sampling 알고리즘의 inputs로 사용된다:x = ceil(inputCoordinate.x - 0.5) y = ceil(inputCoordinate.y - 0.5) output tensor value = input tensor value at (x, y)
linear-
위에서 계산된
inputCoordinate.x및inputCoordinate.y는 output tensor 값을 다음과 같이 계산하기 위해 bilinear sampling 알고리즘의 inputs로 사용된다:x0 = floor(inputCoordinate.x) x1 = ceil(inputCoordinate.x) y0 = floor(inputCoordinate.y) y1 = ceil(inputCoordinate.y) vx0y0 = input tensor value at (x0, y0) vx1y0 = input tensor value at (x1, y0) vx0y1 = input tensor value at (x0, y1) vx1y1 = input tensor value at (x1, y1) tx = inputCoordinate.x - x0 ty = inputCoordinate.y - y0 vy0 = vx0y0 * (1 - tx) + vx1y0 * tx vy1 = vx0y1 * (1 - tx) + vx1y1 * tx output tensor value = vy0 * (1 - ty) + vy1 * ty
scales, 타입은 sequence<float>-
길이 2의 list.
axes의 각 input dimension에 대한 scaling factor를 지정한다: [scaleForFirstAxis, scaleForSecondAxis]. 기본값은 [1.0, 1.0]이다. sizes, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list.
axes의 각 input dimension에 대한 target sizes를 지정한다: [sizeForFirstAxis, sizeForSecondAxis].sizes가 지정되면, scaling factor 값은 input의 target sizes에서 파생되므로scales는 무시된다. axes, 타입은sequence<[EnforceRange] unsigned long>-
길이 2의 list. interpolation 알고리즘이 적용되는 input tensor의 두 dimensions를 지정한다. 기본값은 [2, 3]이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16",
"uint8",
"int8"
| "float32",
"float16"
| 4 | 4 |
| output | 동일 input
| "float32",
"float16"
| 4 | 4 |
MLOpSupportLimits에는
resample2d()에
대해 다음 멤버가 있다:
resample2d, 타입은 MLSingleInputSupportLimits-
resample2d()operator에 대한 지원 제한.
resample2d(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그렇지 않고, 그것의 items 중 어느 하나라도 0보다 작거나 같거나, 그것의 size가 2가 아니면,
TypeError를 throw한다. -
options.
sizes가 존재하고, 그것의 size가 2가 아니거나, 또는 그것의 items 중 어느 하나라도 0이면,TypeError를 throw한다. -
그렇지 않고, options.
axes가 중복 값을 포함하거나, 그것의 items 중 어느 하나라도 범위 0부터 input의 rank까지(끝값 제외) 안에 없으면,TypeError를 throw한다. -
output shape 계산하기:
-
inputDescriptor를 input.
[[descriptor]]로 둔다. -
desc를 inputDescriptor.
dataType와 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
-
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options가 주어진 "resample2d" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
linear
resampling을 수행할 때(spatial dimensions만 고려):
[ 0 1 2 3 ] [ 0 1 2 3 ] [ 12 13 14 15 ] [ 12 13 14 15 ]
[8, 8] output tensor에 대해, 기대되는 값은 다음과 같다:
[ 0 0.25 0.75 1.25 1.75 2.25 2.75 3 ] [ 0 0.25 0.75 1.25 1.75 2.25 2.75 3 ] [ 0 0.25 0.75 1.25 1.75 2.25 2.75 3 ] [ 3 3.25 3.75 4.25 4.75 5.25 5.75 6 ] [ 9 9.25 9.75 10.25 10.75 11.25 11.75 12 ] [ 12 12.25 12.75 13.25 13.75 14.25 14.75 15 ] [ 12 12.25 12.75 13.25 13.75 14.25 14.75 15 ] [ 12 12.25 12.75 13.25 13.75 14.25 14.75 15 ]
이는 sampling이 균등하게 분포되고, 대칭적이며, image mirroring에 견고하고, corner 값이 align된다는 편리한 속성을 가진다.
8.9.42. reshape
tensor의 shape를 새 shape로 변경한다. Reshape는 tensor의 content를 copy하거나 변경하지 않는다. 후속 연산을 위해 tensor의 logical shape만 변경한다.partial interface MLGraphBuilder {MLOperand reshape (MLOperand input ,sequence <[EnforceRange ]unsigned long >newShape ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits reshape ; };
-
input:MLOperand. input tensor. -
newShape: sequence<unsigned long>. output tensor의 shape.newShape가 암시하는 element 수는 input tensor의 element 수와 같아야 한다. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
output tensor. output tensor의 값은 input tensor의 값과 같다. output tensor의 shape는 newShape로
지정된다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32",
"int8",
"uint8"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32",
"int8",
"uint8"
| N | 0부터 5까지 |
MLOpSupportLimits에는
reshape()에
대해 다음 멤버가 있다:
reshape, 타입은 MLSingleInputSupportLimits-
reshape()operator에 대한 지원 제한.
reshape(input, newShape, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
newShape의 size가 (이 표에 따른) output tensor의 허용되는 rank가 아니면,
TypeError를 throw한다. -
outputShape를
unsigned long의 빈 배열로 둔다. -
inputElementCount를 input의 shape에 있는 모든 items의 곱으로 둔다. 빈 dimensions는 inputElementCount를 1로 산출한다.
-
newShape의 모든 값의 곱이 inputElementCount와 같지 않으면,
TypeError를 throw한다. -
desc를 input.
[[descriptor]]의 복사본으로 둔다. -
desc.
shape를 newShape로 설정한다. -
graph 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 options가 주어진 "reshape" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.43. reverse
주어진 axes를 따라 tensor를 reverse한다.dictionary :MLReverseOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >axes ; };partial interface MLGraphBuilder {MLOperand reverse (MLOperand input ,optional MLReverseOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits reverse ; };
MLReverseOptions는
다음 멤버를 가진다:
axes, 타입은sequence<[EnforceRange] unsigned long>-
reverse할 input dimensions에 대한 indices. 이 멤버가 존재하지 않으면 모든 dimensions가 reverse되는 것처럼 처리된다. 명시적으로 빈 값으로 전달되면 어떤 dimensions도 reverse되지 않는다.
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
reverse()에
대해 다음 멤버가 있다:
reverse, 타입은 MLSingleInputSupportLimits-
reverse()operator에 대한 지원 제한.
reverse(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
inputRank를 input의 rank로 둔다.
-
axes가 주어지지 않았으면, axes를 범위 0부터 inputRank까지(끝값 제외)로 둔다.
-
그렇지 않고, axes가 중복 값을 포함하거나, 그 elements 중 어느 하나라도 범위 0부터 inputRank까지(끝값 제외)에 없으면, failure를 반환한다.
-
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 "reverse" operation과 options에 대한 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.44. scatterElements
indices에 따라 axis를 따라 input tensor의 copy 위에 updates tensor의 값들을 scatter한다.dictionary :MLScatterOptions MLOperatorOptions { [EnforceRange ]unsigned long axis = 0; };partial interface MLGraphBuilder {MLOperand scatterElements (MLOperand input ,MLOperand indices ,MLOperand updates ,optional MLScatterOptions options = {}); };dictionary {MLScatterSupportLimits MLTensorLimits input ;MLTensorLimits indices ;MLTensorLimits updates ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLScatterSupportLimits scatterElements ; };
MLScatterOptions는
다음 멤버를 가진다:
axis, 타입은 unsigned long, 기본값은0-
scattered values가 얻어지는 axis. 그 값은 [0, N-1] 범위 안에 있어야 하며, 여기서 N은 input tensor의 rank이다.
-
input:MLOperand. output을 초기화하는 데 사용할 input N-D tensor. -
indices:MLOperand. scatter할 input 값의 indices N-D tensor. 값은"int32","uint32", 또는"int64"타입이어야 하며, options.axis로 index된 input dimension의 size를 N이라고 할 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 한다. 음수 index는 dimension의 끝에서부터 indexing함을 의미한다. -
updates:MLOperand. indices와 같은 shape를 가지며 input 위에 대체할 새 값. -
options: 선택적MLScatterOptions. operation의 선택적 매개변수.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
indices
| "int32",
"uint32",
"int64"
| "int32"
| 동일 input
| 1부터 5까지 |
updates
| 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 1부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 1부터 5까지 |
MLScatterSupportLimits에는
다음 멤버가 있다:
input, 타입은 MLTensorLimits-
MLTensorLimits는 input operand에 대한 것이다. indices, 타입은 MLTensorLimits-
MLTensorLimits는 indices operand에 대한 것이다. updates, 타입은 MLTensorLimits-
MLTensorLimits는 updates operand에 대한 것이다. output, 타입은 MLTensorLimits-
MLTensorLimits는 output operand에 대한 것이다.
MLOpSupportLimits에는
scatterElements()에
대해 다음 멤버가 있다:
scatterElements, 타입은 MLScatterSupportLimits-
scatterElements()operator에 대한 지원 제한.
indices
매개변수는 graph가 build될 때 input이 execution 전까지 알려지지 않으므로, scatterElements()에
대해 허용된 범위로 clamp될 수 없다. 지정된 clamping 동작이 하위 플랫폼에서 제공되지 않으면,
구현은 compiled graph에 clamp()를
도입할 수 있다.
마찬가지로, 하위 플랫폼이 음수 indices를 지원하지 않으면, 구현은 dimension의 끝에서부터의 음수 index를 양수
index로 변환하는 operation을 compiled graph에 도입할 수 있다.
scatterElements(input, indices, updates, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, indices 및 updates 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
updates의 dataType이 input의 dataType과 같지 않으면,
TypeError를 throw한다. -
input, indices 또는 updates 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
axis를 options.
axis로 둔다. -
indicesShapeExpected를 input의 shape의 복사본으로 둔다.
-
indicesShapeExpected[axis]를 indices의 shape[axis]로 설정한다.
-
indices의 shape가 indicesShapeExpected와 같지 않으면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 input, indices, updates 및 options가 주어진 "scatterElements" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input, indices, 및 updates로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
서로 다른 slicing schemes에서 scatterElements가 동작하는 방식의 예.
// shape [4,3]의 input: // [[ 0, 1, 2], // [10, 11, 12], // [20, 21, 22], // [30, 31, 32]] // shape [2,3]의 indices: // [[3, 1, 1], // [2, 0, 3]] // shape [2,3]의 updates: // [[-1, -2, -3], // [-4, -5, -6]] // axis = 0 (기본값) // shape [4,3]의 output: // [[ 0, -5, 2], // [10, -2, -3], // [-4, 21, 22], // [-1, 31, -6]] const input1= builder. constant( { dataType: 'float32' , shape: [ 4 , 3 ]}, new Float32Array([ 0 , 1 , 2 , 10 , 11 , 12 , 20 , 21 , 22 , 30 , 31 , 32 ])); const indices1= builder. constant( { dataType: 'uint32' , shape: [ 2 , 3 ]}, new Uint32Array([ 3 , 1 , 1 , 2 , 0 , 3 ])); const updates1= builder. constant( { dataType: 'float32' , shape: [ 2 , 3 ]}, new Uint32Array([ - 1 , - 2 , - 3 , - 4 , - 5 , - 6 ])); const output1= builder. scatterElements( input1, indices1, updates1); // shape [4,3]의 input: // [[ 0, 1, 2], // [10, 11, 12], // [20, 21, 22], // [30, 31, 32]] // shape [4,1]의 indices: // [[2], // [1], // [0], // [2]], // shape [4,1]의 updates: // [[-1], // [-2], // [-3], // [-4]], // axis = 1 // shape [4,3]의 output: // [[ 0, 1, -1], // [10, -2, 12], // [-3, 21, 22], // [30, 31, -4]] const indices2= builder. constant( { dataType: 'uint32' , shape: [ 4 , 1 ]}, new Uint32Array([ 2 , 1 , 0 , 2 ])); const updates2= builder. constant( { dataType: 'float32' , shape: [ 4 , 1 ]}, new Uint32Array([ - 1 , - 2 , - 3 , - 4 ])); const output2= builder. scatterElements( input1, indices2, updates2, { axis: 1 }); // shape [4,2,2]의 input: // [[[ 0, 1], // [ 10, 11]], // [[100, 101], // [110, 111]], // [[200, 201], // [210, 211]], // [[300, 301], // [310, 311]],] // shape [1,2,2]의 indices: // [[[0, 2], // [1, 3]]], // shape [1,2,2]의 updates: // [[[-1, -2], // [-3, -4]]], // axis = 0 // shape [4,2,2]의 output: // [[[ -1, 1], // [ 10, 11]], // [[100, 101], // [ -3, 111]], // [[200, -2], // [210, 211]], // [[300, 301], // [310, -4]],] const inputData3= new Float32Array( [ 0 , 1 , 10 , 11 , 100 , 101 , 110 , 111 , 200 , 201 , 210 , 211 , 300 , 301 , 310 , 311 ]); const input3= builder. constant({ dataType: 'float32' , shape: [ 4 , 2 , 2 ]}, inputData3); const indices3= builder. constant( { dataType: 'uint32' , shape: [ 1 , 2 , 2 ]}, new Uint32Array([ 0 , 2 , 1 , 3 ])); const updates3= builder. constant( { dataType: 'float32' , shape: [ 1 , 2 , 2 ]}, new Uint32Array([ - 1 , - 2 , - 3 , - 4 ])); const output3= builder. scatterElements( input3, indices3, updates3, { axis: 0 });
8.9.45. scatterND
indices에 따라 input tensor의 copy 위에 update tensor의 값 slice를 scatter한다.partial interface MLGraphBuilder {MLOperand scatterND (MLOperand input ,MLOperand indices ,MLOperand updates ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLScatterSupportLimits scatterND ; };
-
input:MLOperand. output을 초기화하는 데 사용할 input N-D tensor. -
indices:MLOperand. indices 배열은 output tensor에 대한 전체 좌표를 포함하며, 가장 오른쪽 dimension은 좌표당 dimension의 수를 담는다. 따라서 shape가 [10,1]인 indices tensor는 10개의 단일 축 indices를 담고, shape가 [4,3]이면 3D 좌표의 4개 indices를 담는다. 값은"int32","uint32", 또는"int64"타입이어야 하며, 각 값은 대응하는 output dimension의 size를 N이라고 할 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 한다. 음수 index는 대응하는 dimension의 끝에서부터 indexing함을 의미한다. -
updates:MLOperand. input 위에 대체할 새 값. -
options: 선택적MLScatterOptions. operation의 선택적 매개변수.
반환: MLOperand.
input의
rank + indices의
rank - indices의
shape[-1] - 1과
같은 rank를 가지는 output N-D
tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
indices
| "int32",
"uint32",
"int64"
| "int32"
| 1부터 N까지 | 1부터 5까지 |
updates
| 동일 input
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
MLOpSupportLimits에는
scatterND()에
대해 다음 멤버가 있다:
scatterND, 타입은 MLScatterSupportLimits-
scatterND()operator에 대한 지원 제한.
indices
매개변수는 graph가 build될 때 input이 execution 전까지 알려지지 않으므로, scatterND()에
대해 허용된 범위로 clamp될 수 없다. 지정된 clamping 동작이 하위 플랫폼에서 제공되지 않으면,
구현은 compiled graph에 clamp()를
도입할 수 있다.
마찬가지로, 하위 플랫폼이 음수 indices를 지원하지 않으면, 구현은 dimension의 끝에서부터의 음수 index를 양수
index로 변환하는 operation을 compiled graph에 도입할 수 있다.
scatterND(input, indices, updates, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input, indices 및 updates 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
updates의 dataType이 input의 dataType과 같지 않으면,
TypeError를 throw한다. -
input, indices 또는 updates 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
indicesShape를 indices의 shape로 두고, indicesRank를 indices의 rank로 둔다.
-
indexableSize를 indicesRank - 1로 둔다.
-
coordinateSize를 indicesShape[indexableSize]로 둔다.
-
expectedUpdatesShape를 빈 list로 둔다.
-
각 index에 대해, 범위 0부터 indexableSize까지(끝값 제외):
-
indicesShape[index]를 expectedUpdatesShape에 append한다.
-
-
각 index에 대해, 범위 coordinateSize부터 inputRank까지(끝값 제외):
-
inputShape[index]를 expectedUpdatesShape에 append한다.
-
-
updates의 shape가 expectedUpdatesShape와 같지 않으면,
TypeError를 throw한다. -
outputShape를 input의 shape의 복사본으로 둔다.
-
outputDesc를 input의 dataType과 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 outputDesc가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 input, indices, updates 및 options가 주어진 "scatterND" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 input, indices, 및 updates로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
서로 다른 slicing schemes에서 scatterND가 동작하는 방식의 예.
// shape [8]의 input: // [0, 1, 2, 3, 4, 5, 6, 7] // shape [4, 1]의 indices: // [[4], // [3], // [1], // [7]] // shape [4]의 updates: // [-1, -2, -3, -4] // shape [8]의 output: // [0, -3, 2, -2, -1, 5, 6, -4] const input1= builder. constant( { dataType: 'float32' , shape: [ 8 ]}, new Float32Array([ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ])); const indices1= builder. constant( { dataType: 'uint32' , shape: [ 4 , 1 ]}, new Uint32Array([ 4 , 3 , 1 , 7 ])); const updates1= builder. constant( { dataType: 'uint32' , shape: [ 4 ]}, new Uint32Array([ - 1 , - 2 , - 3 , - 4 ])); const output1= builder. scatterND( input1, indices1, updates1); // shape [2,2]의 input: // [[0, 1], // [2, 3]] // shape [2,2]의 indices: // [[0, 0], // [1, 1]] // shape [2]의 updates: // [-1, -2] // shape [2,2]의 output: // [[-1, 1], <= -1이 output coordinate [0, 0]에 쓰임 // [ 2, -2]] <= -2가 output coordinate [1, 1]에 쓰임 const input2= builder. constant( { dataType: 'float32' , shape: [ 2 , 2 ]}, new Float32Array([ 0 , 1 , 2 , 3 ])); const indices2= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ 0 , 0 , 1 , 1 ])); const updates2= builder. constant({ dataType: 'uint32' , shape: [ 2 ]}, new Uint32Array([ - 1 , - 2 ])); const output2= builder. scatterND( input2, indices2, updates2); // shape [3,2]의 input: // [[0, 1], // [2, 3], // [4, 5]] // shape [2,1]의 indices: // [[2], // [0]] // shape [2,2]의 updates: // [[-1, -2], // [-3, -4]] // shape [3,2]의 output: // [[-3 ,-4], <= [-3, -4]가 output coordinates [0, *]에 쓰임 // [ 2, 3], // [-1, -2]] <= [-1, -2]가 output coordinates [2, *]에 쓰임 const input3= builder. constant( { dataType: 'float32' , shape: [ 3 , 2 ]}, new Float32Array([ 0 , 1 , 2 , 3 , 4 , 5 ])); const indices3= builder. constant( { dataType: 'uint32' , shape: [ 2 , 1 ]}, new Uint32Array([ 1 , 0 ])); const updates3= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ - 1 , - 2 , - 3 , 4 ])); const output3= builder. scatterND( input3, indices3, updates3); // shape [2,2,2]의 input: // [[[0, 1], // [2, 3]], // [[4, 5], // [6, 7]]] // shape [2,2]의 indices: // [[0, 1], // [1, 0]] // shape [2,2]의 updates: // [[-1, -2], // [-3, -4]] // shape [2,2,2]의 output: // [[[ 0, 1], // [-1, -2]], <= [-1, -2]가 output coordinates [0, 1, *]에 쓰임 // [[-3, -4], <= [-3, -4]가 output coordinates [1, 0, *]에 쓰임 // [ 6, 7]]] const input4= builder. constant( { dataType: 'float32' , shape: [ 2 , 2 , 2 ]}, new Float32Array([ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ])); const indices4= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ 0 , 1 , 1 , 0 ])); const updates4= builder. constant( { dataType: 'uint32' , shape: [ 2 , 2 ]}, new Uint32Array([ - 1 , - 2 , - 3 , 4 ])); const output4= builder. scatterND( input4, indices4, updates4);
8.9.46. sigmoid
input tensor의 sigmoid function을 계산한다. 계산은1 / (exp(-x) + 1) 식을 따른다.
partial interface MLGraphBuilder {MLOperand sigmoid (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits sigmoid ; };
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
sigmoid()에
대해 다음 멤버가 있다:
sigmoid, 타입은 MLSingleInputSupportLimits-
sigmoid()operator에 대한 지원 제한.
sigmoid(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "sigmoid" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function sigmoid( builder, input) { return builder. div( builder. constant( input. dataType, 1 ), builder. add( builder. exp( builder. neg( input)), builder. constant( input. dataType, 1 ))); }
8.9.47. slice
input tensor의 slice를 생성한다.dictionary :MLSliceOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >strides ; };partial interface MLGraphBuilder {MLOperand slice (MLOperand input ,sequence <[EnforceRange ]unsigned long >starts ,sequence <[EnforceRange ]unsigned long >sizes ,optional MLSliceOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits slice ; };
MLSliceOptions는
다음 멤버를 가진다:
strides, 타입은sequence<[EnforceRange] unsigned long>-
각 axis를 따라 각 input을 건너뛰는 stride. strides array의 길이는 input tensor의 rank와 같아야 한다. 기본값은 모두 1로 구성된 길이 rank의 array이다. 예: 3-D tensor의 경우 [1,1,1]. Strides는 0보다 커야 한다.
-
input:MLOperand. input tensor. -
starts: sequence<unsigned long>. 각 input dimension의 slice 시작 index로, 길이는 N이며 여기서 N은 input tensor의 rank이다.input의 각 dimension d에 대해,starts[d] 는 해당 dimension에서 slice할 시작 index를 나타낸다. 시작 index는 해당 dimension에서 [0, input size - 1] 범위 안에 있어야 한다. -
sizes: sequence<unsigned long>. 각 input dimension에서 slice할 element 수로, 길이는 N이며 여기서 N은 input tensor의 rank이다.input의 각 dimension d에 대해,sizes[d] 는 해당 dimension에서 slice할 element 수를 나타낸다. size는 0이어서는 안 되며, 해당 dimension에서starting index + size <= input size제약을 만족해야 한다. -
options:MLSliceOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
input tensor와 같은 rank를 가지며, 각 dimension에서 지정된 starting 및 ending indices로 tensor 값이
잘라진 output tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32",
"int8",
"uint8"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32",
"int8",
"uint8"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits는
slice()에
대해 다음 멤버를 가진다:
slice, 타입은 MLSingleInputSupportLimits-
slice()오퍼레이터에 대한 지원 제한.
slice(input, starts, sizes, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
starts의 size와 sizes의 size가 모두 input의 rank와 같지 않으면,
TypeError를 throw한다. -
strides를 새 list로 둔다.
-
outputShape를 새 list로 둔다.
-
0부터 inputRank까지의 range에 있는 각 index에 대해 For each, exclusive:
-
inputSize를 inputShape[index]로 둔다.
-
inputSliceSize를 sizes[index]로 둔다.
-
stride를 비어 있지 않으면 strides[index]로, 그렇지 않으면 1로 둔다:
-
inputSliceSize가 0이면,
TypeError를 throw한다.0-size dimensions가 허용된다면, 이 단계들을 수정한다. [Issue #391]
-
starts[index] + inputSliceSize가 inputSize보다 크면,
TypeError를 throw한다. -
outputSizeRoundingExcess를 inputSliceSize % stride != 0이면 1, 그렇지 않으면 0으로 둔다.
-
outputSize를 floor(inputSliceSize / stride) + outputSizeRoundingExcess로 둔다:
-
outputSize를 outputShape에 append한다.
-
-
outputDesc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 outputDesc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 starts, sizes 및 options가 주어진 "slice" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.48. softmax
주어진 axis를 따라 N-D input tensor의 softmax 값을 계산한다.partial interface MLGraphBuilder {MLOperand softmax (MLOperand input , [EnforceRange ]unsigned long axis ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits softmax ; };
-
input:MLOperand. input N-D tensor. -
axis:unsigned longscalar. reduction이 수행될 dimension. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| 1부터 N까지 | 1부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 1부터 5까지 |
MLOpSupportLimits에는
softmax()에
대해 다음 멤버가 있다:
softmax, 타입은 MLSingleInputSupportLimits-
softmax()operator에 대한 지원 제한.
softmax(input, axis, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 axis와 options가 주어진 "softmax" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function softmax( builder, input, axis) { // 이 sample은 결과의 numerical stability를 높이기 위해 input 값 자체의 exponentials 대신 // max 값까지의 거리의 exponentials를 계산하는 잘 알려진 구현 trick [1]을 사용한다. // [1]: https://cs231n.github.io/linear-classify/#softmax const maxX= builder. reduceMax( input, { axes: [ axis], keepDimensions: true }); const expX= builder. exp( builder. sub( input, maxX)); return builder. div( expX, builder. reduceSum( expX, { axes: [ axis], keepDimensions: true })); }
8.9.49. softplus
input tensor의 softplus function을 계산한다. 계산은ln(1 + exp(x)) 식을 따른다.
partial interface MLGraphBuilder {MLOperand softplus (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits softplus ; };
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
softplus()에
대해 다음 멤버가 있다:
softplus, 타입은 MLSingleInputSupportLimits-
softplus()operator에 대한 지원 제한.
softplus(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 "softplus" operation 및 options에 대한 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function softplus( builder, input) { return builder. log( builder. add( builder. exp( input), builder. constant( input. dataType, 1 ))); }
8.9.50. softsign
input tensor의 softsign function을 계산한다. 계산은x / (1 + |x|) 식을 따른다.
partial interface MLGraphBuilder {MLOperand softsign (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits softsign ; };
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function softsign( builder, input) { return builder. div( input, builder. add( builder. constant( input. dataType, 1 ), builder. abs( input))); }
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
softsign()에
대해 다음 멤버가 있다:
softsign, 타입은 MLSingleInputSupportLimits-
softsign()operator에 대한 지원 제한.
softsign(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 "softsign" operation 및 options에 대한 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.51. split
주어진 axis를 따라 input tensor를 여러 sub tensors로 분할한다.dictionary :MLSplitOptions MLOperatorOptions { [EnforceRange ]unsigned long axis = 0; };partial interface MLGraphBuilder {sequence <MLOperand >split (MLOperand input , ([EnforceRange ]unsigned long or sequence <[EnforceRange ]unsigned long >)splits ,optional MLSplitOptions options = {}); };dictionary {MLSplitSupportLimits MLTensorLimits input ;MLTensorLimits outputs ; };partial dictionary MLOpSupportLimits {MLSplitSupportLimits split ; };
-
input:MLOperand. input tensor. -
splits:unsigned long또는 sequence<unsigned long>.unsigned long이면, axis를 따라 output tensors의 수를 지정한다. 그 수는input의axis를 따른 dimension size를 균등하게 나눌 수 있어야 한다. sequence<unsigned long>이면,axis를 따라 각 output tensor의 size를 지정한다. size의 합은input의axis를 따른 dimension size와 같아야 한다. -
options: 선택적MLSplitOptions. 연산의 선택적 매개변수.
반환: sequence<MLOperand>.
분할된 output tensors. splits가
unsigned long이면,
output의 size는 splits와
같다. 각 output tensor의 shape는 input과
같지만, axis의
dimension size는 input의
axis를
따른 dimension size를 splits로
나눈 몫과 같다.
splits가
sequence<unsigned long>이면,
output의 size는 splits의
size와 같다.
i번째 output tensor의 shape는 input과
같지만, axis를
따른 dimension size는 splits[i]이다.
MLSplitOptions는
다음 멤버를 가진다:
axis, 타입은 unsigned long, 기본값은0-
분할할 dimension. 그 값은 [0, N-1] 범위 안에 있어야 하며, 여기서 N은 input tensor의 rank이다.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| 1부터 N까지 | 1부터 5까지 |
| outputs | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 1부터 5까지 |
MLSplitSupportLimits는
다음 멤버를 가진다:
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. outputs, 타입은 MLTensorLimits-
모든 output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
split()에
대해 다음 멤버를 가진다:
split, 타입은 MLSplitSupportLimits-
split()오퍼레이터에 대한 지원 제한.
split(input, splits, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
axis를 options.
axis로 둔다. -
splits가
unsigned long이면: -
splits가 sequence<
unsigned long>이면: -
그래프 연결 만들기:
-
operator를 splits 및 options가 주어진 "split" 연산에 대한 오퍼레이터로 둔다.
-
outputs를 새 list로 둔다.
-
0부터 splitCount까지의 range에 있는 각 index에 대해 For each, exclusive:
-
operand를 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
splits가
unsigned long이면, newDimension을 operand의 shape[axis] / splits로 둔다. -
그렇지 않으면, newDimension을 splits[index]로 둔다.
-
operand의 shape[axis]를 newDimension으로 설정한다.
-
operand.
[[operator]]를 operator로 설정한다. -
operand를 outputs에 append한다.
-
-
operator의 input을 input으로 설정한다.
-
operator의 outputs를 outputs로 설정한다.
-
-
outputs를 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function split( builder, input, splits, options) { // 이 sample은 splits parameter가 array인 경우를 보여준다. const outputs= []; const inputShape= input. shape; const inputRank= inputShape. length; let starts= Array( inputRank). fill( 0 ); let sizes= inputShape; let start= 0 ; for ( const sizeof splits) { starts[ options. axis] = start; sizes[ options. axis] = size; outputs. push( builder. slice( input, starts, sizes)); start+= size; } return outputs; }
8.9.52. tanh
input tensor의 hyperbolic tangent function을 계산한다. 계산은(exp(2 * x) - 1) / (exp(2 * x) + 1) 식을 따른다.
partial interface MLGraphBuilder {MLOperand tanh (MLOperand input ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits tanh ; };
-
input:MLOperand. input tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환:
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| "float32",
"float16"
| "float32",
"float16"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits에는
tanh()에
대해 다음 멤버가 있다:
tanh, 타입은 MLSingleInputSupportLimits-
tanh()operator에 대한 지원 제한.
tanh(input, options) 메서드
단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "tanh" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function tanh( builder, input) { return builder. div( builder. sub( builder. exp( builder. mul( builder. constant( input. dataType, 2 ), input)), builder. constant( input. dataType, 1 )), builder. add( builder. exp( builder. mul( builder. constant( input. dataType, 2 ), input)), builder. constant( input. dataType, 1 ))); }
8.9.53. tile
각 dimension을 따라 주어진 횟수만큼 tensor를 반복한다.partial interface MLGraphBuilder {MLOperand tile (MLOperand input ,sequence <unsigned long >repetitions ,optional MLOperatorOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits tile ; };
-
input:MLOperand. input N-D tensor. -
repetitions: 해당 dimension을 몇 번 반복할지를 나타내는 dimension별 count. size는input의 rank와 일치해야 하며, 같은 size를 유지해야 하는 axis에는 1을 사용한다. -
options: 선택적MLOperatorOptions. 연산의 선택적 매개변수.
반환: MLOperand.
반전된 N-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits는
tile()에
대해 다음 멤버들을 가진다:
tile, 타입은 MLSingleInputSupportLimits-
tile()오퍼레이터에 대한 지원 제한.
tile(input, repetitions, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
repetitions의 값들에 0이 포함되어 있으면,
TypeError를 throw한다.0-size dimensions가 허용된다면, 이 단계들을 수정한다. [Issue #391]
-
outputShape를 input의 shape의 copy로 둔다.
-
0부터 outputShape의 size까지의 range에 있는 각 index에 대해 For each, exclusive:
-
outputShape[index]를 outputShape[index] * repetitions[index]로 설정한다.
-
-
outputDescriptor를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 outputDescriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 "tile" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.54. transpose
permutation에
따라 input tensor의 dimensions를 permute한다.
dictionary :MLTransposeOptions MLOperatorOptions {sequence <[EnforceRange ]unsigned long >permutation ; };partial interface MLGraphBuilder {MLOperand transpose (MLOperand input ,optional MLTransposeOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits transpose ; };
MLTransposeOptions는
다음 멤버를 가진다:
permutation, 타입은sequence<[EnforceRange] unsigned long>-
output shape를 permute하는 데 사용되는 값들. 기본값은 [N-1, ..., 0]이며, 여기서 N은 input tensor의 rank이다. 예: 3-D tensor의 경우 [2,1,0]. 이러한 기본값은 output이 input의 transposed tensor가 되게 한다. 지정된 경우, 값의 수는 input tensor의 rank와 같아야 하며, 값은 중복 없이 0부터 N-1까지의 범위 안에 있어야 한다.
-
input:MLOperand. input N-D tensor. -
options: 선택적MLTransposeOptions. 연산의 선택적 매개변수.
반환: MLOperand.
permuted 또는 transposed N-D tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 input
| "float32",
"float16",
"int32"
| 동일 input
| 0부터 5까지 |
MLOpSupportLimits는
transpose()에
대해 다음 멤버를 가진다:
transpose, 타입은 MLSingleInputSupportLimits-
transpose()오퍼레이터에 대한 지원 제한.
transpose(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
options.
permutation이 존재하지 않으면, options.permutation을 input의 shape에 대한 모든 indices의 reversed sequence로 둔다. -
그렇지 않고, options.
permutation이 존재하면: -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "transpose" 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
8.9.55. triangular
2-D tensor(matrix)가 주어지면, input tensor의 upper 또는 lower triangular part를 포함하는 2-D tensor를 반환한다. input tensor가 2보다 큰 dimensions를 가지면, 이는 matrices의 batch로 취급되며 결과는 같은 shape를 가진다.dictionary :MLTriangularOptions MLOperatorOptions {boolean upper =true ; [EnforceRange ]long diagonal = 0; };partial interface MLGraphBuilder {MLOperand triangular (MLOperand input ,optional MLTriangularOptions options = {}); };partial dictionary MLOpSupportLimits {MLSingleInputSupportLimits triangular ; };
MLTriangularOptions는
다음 멤버를 가진다:
upper, 타입은 boolean, 기본값은true-
input matrix의 upper part 또는 lower part 중 output에 유지되는 부분을 나타낸다. True는 upper part가 유지됨을 나타낸다.
diagonal, 타입은 long, 기본값은0-
input matrix의 main diagonals 위 또는 아래 몇 개의 diagonals가 유지되거나 제외되는지를 지정한다. 값 0은 main diagonals 이외의 diagonals에는 영향이 없음을 의미한다.
-
input:MLOperand. 최소 2-D인 input tensor. -
options: 선택적MLTriangularOptions. 연산의 선택적 매개변수.
반환: MLOperand.
triangular matrix, 또는 input과 같은 shape의 matrices batch를 나타내는 output tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
input
| any | "float32",
"float16"
| 2부터 N까지 | 2부터 5까지 |
| output | 동일 input
| "float32",
"float16"
| 동일 input
| 2부터 5까지 |
MLOpSupportLimits에는
triangular()에
대해 다음 멤버가 있다:
triangular, 타입은 MLSingleInputSupportLimits-
triangular()operator에 대한 지원 제한.
triangular(input, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 input으로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
input의 rank가 (이 표에 따른) 그 허용되는 rank 중 하나가 아니면,
TypeError를 throw한다. -
graph 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand 복사하기의 결과로 둔다.
-
operator를 options가 주어진 "triangular" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
서로 다른 diagonal 설정에서 triangular가 동작하는 방식의 예.
// input: // [[7, 1, 2], // [9, 4, 8], // [2, 6, 3]] const input= builder. constant( { dataType: 'float32' , shape: [ 3 , 3 ]}, new Float32Array([ 7 , 1 , 2 , 9 , 4 , 8 , 2 , 6 , 3 ])); // upper triangular matrix: // [[7, 1, 2], // [0, 4, 8], // [0, 0, 3]] const upper= builder. triangular( input); // diagonals 한 세트를 추가로 제외한 upper triangular matrix: // [[0, 1, 2], // [0, 0, 8], // [0, 0, 0]] const upperPositive= builder. triangular( input, { diagonal: 1 }); // diagonals 한 세트를 추가로 유지한 upper triangular matrix: // [[7, 1, 2], // [9, 4, 8], // [0, 6, 3]] const upperNegative= builder. triangular( input, { diagonal: - 1 }); // lower triangular matrix: // [[7, 0, 0], // [9, 4, 0], // [2, 6, 3]] const lower= builder. triangular( input, { upper: false }); // diagonals 한 세트를 추가로 유지한 lower triangular matrix: // [[7, 1, 0], // [9, 4, 8], // [2, 6, 3]] const lowerPositive= builder. triangular( input, { upper: false , diagonal: 1 }); // diagonals 한 세트를 추가로 제외한 lower triangular matrix: // [[0, 0, 0], // [9, 0, 0], // [2, 6, 0]] const lowerNegative= builder. triangular( input, { upper: false , diagonal: - 1 }) // 두 batch가 있는 lower triangular matrix: // [[[7, 0, 0], // [9, 4, 0], // [2, 6, 3]], // [[1, 0, 0], // [4, 5, 0], // [7, 8, 9]]] const lowerWithBatches= builder. triangular( input, { upper: false });
8.9.56. where
condition
tensor의 대응하는 값에 따라 trueValue
또는 falseValue
tensor에서 값을 선택한다. 여기서 non-zero는 true이고 zero는 false이다. condition
tensor는 흔히 element-wise logical operations 중 하나의 output이다.
이 연산은 broadcast되며, [numpy-broadcasting-rule]를 따른다. input tensors는 bidirectionally broadcastable이어야 한다. output tensor의 rank는 input tensors의 최대 rank이다. output tensor의 각 dimension에 대해, 그 size는 input tensors의 해당 dimension을 따른 최대 size이다.
partial interface MLGraphBuilder {MLOperand where (MLOperand condition ,MLOperand trueValue ,MLOperand falseValue ,optional MLOperatorOptions options = {}); };dictionary {MLWhereSupportLimits MLTensorLimits condition ;MLTensorLimits trueValue ;MLTensorLimits falseValue ;MLTensorLimits output ; };partial dictionary MLOpSupportLimits {MLWhereSupportLimits where ; };
-
condition:MLOperand. condition tensor. -
trueValue:MLOperand. 대응하는 element의 condition이 true로 설정된 경우 value가 선택되는 tensor. -
falseValue:MLOperand. 대응하는 element의 condition이 false로 설정된 경우 value가 선택되는 tensor. -
options:MLOperatorOptions. 연산의 선택적 매개변수를 지정한다.
반환: MLOperand.
trueValue
또는 falseValue
tensor 중 하나에서 element-wise로 선택된 값들을 포함하는 output tensor.
| operand | 허용되는 데이터 타입 | 필수 데이터 타입 | 허용되는 rank | 필수 rank |
|---|---|---|---|---|
condition
| "uint8"
| "uint8"
| N | 0부터 5까지 |
trueValue
| any | "float32",
"float16",
"int32"
| N | 0부터 5까지 |
falseValue
| 동일 trueValue
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
| output | 동일 trueValue
| "float32",
"float16",
"int32"
| N | 0부터 5까지 |
MLWhereSupportLimits에는
다음 멤버가 있다:
condition, 타입은 MLTensorLimits-
MLTensorLimits는 condition operand에 대한 것이다. trueValue, 타입은 MLTensorLimits-
MLTensorLimits는 trueValue operand에 대한 것이다. falseValue, 타입은 MLTensorLimits-
MLTensorLimits는 falseValue operand에 대한 것이다. output, 타입은 MLTensorLimits-
MLTensorLimits는 output operand에 대한 것이다.
MLOpSupportLimits에는
where()에
대해 다음 멤버가 있다:
where, 타입은 MLWhereSupportLimits-
where()operator에 대한 지원 제한.
where(condition, trueValue, falseValue, options)
메서드 단계는 다음과 같다:
-
this가 build할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
this와 condition, trueValue 및 falseValue 중 어느 하나로 operand 검증을 수행한 결과가 false를 반환하면,
TypeError를 throw한다. -
condition, trueValue 또는 falseValue 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
outputShape를 trueValue의 shape와 falseValue의 shape를 양방향으로 broadcasting한 결과로 둔다.
-
outputShape를 condition의 shape와 outputShape를 양방향으로 broadcasting한 결과로 설정한다.
-
descriptor를 trueValue의 dataType과 outputShape가 주어졌을 때 MLOperandDescriptor 만들기의 결과로 둔다.
-
graph 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand 만들기의 결과로 둔다.
-
operator를 condition, trueValue, falseValue 및 options가 주어진 "where" operation의 operator로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 inputs를 condition, trueValue 및 falseValue로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
이 연산의 동작은 다음과 같이 다른 연산의 사용으로 일반적으로 emulate할 수 있다. 다만 user agents는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우, 이 decomposition은 구현을 안내하는 template으로 사용될 수 있다.
function where( builder, condition, trueValue, falseValue) { const c= builder. clamp( condition, { 'minValue' : 0 , 'maxValue' : 1 }); builder. add( builder. mul( trueValue, builder. cast( c, trueValue. dataType)), builder. mul( falseValue, builder. cast( builder. logicalNot( c), falseValue. dataType))); }
9. 알고리즘
9.1. 브로드캐스팅
Broadcasting은 graph 구성과 계산 중 WebNN이 서로 다른 shape를 가진 tensors를 어떻게 다루는지를 설명한다. 이는 [NumPy]의 영향을 크게 받았으며 [numpy-broadcasting-rule]을 따른다. 대략적으로 말해, 이는 더 작은 tensor에 대한 연산을 더 큰 tensor의 shape 전체로 "broadcast"할 수 있게 하여, 같은 data를 copy하지 않고도 반복적으로 적용할 수 있게 한다.
가장 단순한 예는 add()
또는 mul()
같은 element-wise
binary operations에서 N-dimension tensor에 scalar constant를 적용하는 것이다.
scalar constant의 여러 copy를 포함하는 일치하는 N-dimensional tensor를 allocate하고 채울 필요 없이,
이러한 element-wise operations는 scalar constant를 직접 사용할 수 있게 하고,
scalar 값을 N-dimensional tensor 전체에 broadcast한다. 다음 고려 사항과 함께, 같은
logic은 다른 dimensions의 tensors에도 적용된다.
input tensors의 shapes는 compatible해야 한다. 첫 번째 tensor가 마지막(가장 오른쪽) dimension부터 시작해,
size가 1인 axis를 따라 첫 번째 tensor를 반복하거나 새 dimensions 전체에 반복함으로써 "stretch"될 수 있으면,
tensor는 다른 tensor로 unidirectionally
broadcastable하다.
예를 들어, [4] tensor는 5번 반복하여 [5, 4] tensor로 broadcast할 수 있다.
[1] tensor는 마지막 dimension에서 4번, 앞선 dimension에서 5번 반복하여 [5,4] tensor로
broadcast할 수 있다. Unidirectional broadcasting은 target tensor shape가 명시적으로 주어지는 expand()
같은 operations에서 중요하다.
두 tensors가 마지막 dimension부터 시작해 여러 dimensions 전체에서 서로 "stretch"(반복)될 수 있으면, 두 tensors는 bidirectionally broadcastable하다. 예를 들어, [5,1] tensor는 마지막 dimension에서 첫 번째 tensor를 6번 반복하고 앞선 dimension에서 두 번째 tensor를 5번 반복하여 [1,6] tensor와 bidirectionally broadcast할 수 있다. 연산의 결과는 [5,6] tensor가 된다. Bidirectional broadcasting은 element-wise operations에 편리하다.
모든 dimensions를 integer multiples로 target tensor의 shape까지 upsample할 수 있으면, tensor는 blockwise broadcastable하다. 예를 들어, [4,5] tensor는 정확한 multiple(16 % 4 = 0, 10 % 5 = 0)이므로 첫 번째 dimension에서 모든 element를 4번, 마지막 dimension에서 모든 element를 2번 반복하여 [16,10] tensor까지 blockwise broadcast할 수 있다(예: 마지막 dimensions의 값 [1,2,3,4,5]는 [1,1,2,2,3,3,4,4,5,5]로 반복된다). 그러나 [4,5] tensor는 두 dimensions 모두 nonzero remainder(9 % 4 = 1, 3 % 5 = 3)를 가지므로 [9,3] tensor와 incompatible하다. Blockwise broadcasting은 더 큰 blocks에서 공통 값을 공유하여 memory를 절약하는 데 유용하다. 두 tensors는 같은 rank를 가져야 하며, output shape는 단순히 더 작은 것이 upsample되는 target tensor의 shape이다.
일부 operations는 특별한 semantics로 broadcasting을 허용한다. 예를 들어, matmul()은
input tensors의 마지막 두 dimensions를 matrices의 rows와 columns로 취급하며, 첫 번째 matrix의 columns 수는
두 번째 matrix의 rows 수와 같아야 한다. matrix multiplication은 추가 dimensions 전체에 bidirectionally
broadcast되며, input tensors를 곱할 matrices의 stacks로 취급한다.
shapes shapeFrom 및 shapeTo를 unidirectionally broadcast하려면 다음 단계를 수행한다. shapeFrom과 shapeTo는 tensors의 dimensions를 나타내는 positive integers의 lists이고, 이 단계들은 positive integers의 새 list 또는 failure를 반환한다.
-
sizeFrom을 shapeFrom의 size로 둔다.
-
sizeTo를 shapeTo의 size로 둔다.
-
sizeFrom > sizeTo이면, failure를 반환한다.
-
paddedShapeFrom을 shapeFrom의 clone으로 둔다.
-
paddedShapeFrom의 size가 sizeTo보다 작은 동안, paddedShapeFrom에 1을 prepend한다.
-
outputShape를 새 list로 둔다.
-
0부터 sizeTo까지의 range에 있는 각 index에 대해 For each, exclusive:
-
dimFrom을 paddedShapeFrom[index]로 둔다.
-
dimTo를 shapeTo[index]로 둔다.
-
dimTo가 dimFrom와 같지 않고 dimFrom가 1과 같지 않으면, failure를 반환한다.
-
dimTo를 outputShape에 Append한다.
-
-
outputShape를 반환한다.
shapeFrom과 shapeTo를 unidirectionally broadcasting한 결과가 failure가 아니면, shapeFrom은 shapeTo로 unidirectionally broadcastable하다.
shapes shapeA 및 shapeB를 bidirectionally broadcast하려면 다음 단계를 수행한다. shapeA와 shapeB는 tensors의 dimensions를 나타내는 positive integers의 lists이고, 이 단계들은 positive integers의 새 list 또는 failure를 반환한다.
-
sizeA를 shapeA의 size로 둔다.
-
sizeB를 shapeB의 size로 둔다.
-
outputSize를 sizeA와 sizeB의 maximum으로 둔다.
-
paddedA를 shapeA의 clone으로 둔다.
-
paddedB를 shapeB의 clone으로 둔다.
-
outputShape를 새 list로 둔다.
-
0부터 outputSize까지의 range에 있는 각 index에 대해 For each, exclusive:
-
dimA를 paddedA[index]로 둔다.
-
dimB를 paddedB[index]로 둔다.
-
dimA가 dimB와 같지 않고, dimA가 1과 같지 않고, dimB가 1과 같지 않으면, failure를 반환한다.
-
dimA와 dimB의 maximum을 outputShape에 Append한다.
-
-
outputShape를 반환한다.
shapeA와 shapeB를 bidirectionally broadcasting한 결과가 failure가 아니면, shapeA는 shapeB로 bidirectionally broadcastable하다.
shapes shapeFrom 및 shapeTo를 blockwise broadcast하려면 다음 단계를 수행한다. shapeFrom과 shapeTo는 tensors의 dimensions를 나타내는 positive integers의 lists이고, 이 단계들은 true 또는 false를 반환한다.
shapeFrom과 shapeTo를 blockwise broadcasting한 결과가 true를 반환하면, shapeFrom은 shapeTo로 blockwise broadcastable하다.
9.2. 캐스팅
명시적 numeric casting은 MLNumber
또는 double로
전달된 parameters가 input 또는 output MLOperands의
MLOperandDataType에
맞게 변환되어야 하는 algorithms에서 사용된다.
number x를 주어진 MLOperandDataType
dataType으로 cast하려면,
다음 단계를 수행한다. 이 단계들은 number를 반환한다.
-
dataType에 대해 switch한다:
"float32"-
ConvertToFloat(x, 32)를 반환한다.
"float16"-
ConvertToFloat(x, 16)을 반환한다.
"int64"-
ConvertToInt(x, 64, "signed")를 반환한다.
"uint64"-
ConvertToInt(x, 64, "unsigned")를 반환한다.
"int32"-
ConvertToInt(x, 32, "signed")를 반환한다.
"uint32"-
ConvertToInt(x, 32, "signed")를 반환한다.
"int8"-
ConvertToInt(x, 8, "signed")를 반환한다.
"uint8"-
ConvertToInt(x, 8, "unsigned")를 반환한다.
참고: cast의 input은 special values Infinity, -Infinity 및 NaN을 포함해 range와 precision이 unlimited인 abstract number이다. output도 abstract number이지만, 지정된 type으로 정확히 representable하다.
-
x가 NaN이면, NaN을 반환한다.
-
bitLength에 대해 switch한다:
- 32
-
-
upperBound를 2128로 둔다.
-
lowerBound를 -2128로 둔다.
-
S를 -0을 제외하되 special values upperBound와 lowerBound가 추가된 [IEEE-754-2019] binary32 floating point values의 set으로 둔다.
-
- 16
-
-
upperBound를 216으로 둔다.
-
lowerBound를 -216으로 둔다.
-
S를 -0을 제외하되 special values upperBound와 lowerBound가 추가된 [IEEE-754-2019] binary16 floating point values의 set으로 둔다.
-
-
y를 x에 가장 가까운 S의 number로 둔다. 두 개의 equally close values가 있으면 even significand를 가진 number를 선택한다. 두 special values lowerBound 및 upperBound는 이 목적상 even significands를 가진 것으로 간주한다.
-
y가 upperBound이면, +Infinity를 반환한다.
-
y가 lowerBound이면, -Infinity를 반환한다.
-
y가 +0이고 x가 negative이면, -0을 반환한다.
-
y를 반환한다.
참고: 이는 [WEBIDL]의 정의를 기반으로 하지만, 16-bit floating point values를 다루도록 확장되었다.
-
signedness가 "unsigned"이면:
-
lowerBound를 0으로 둔다.
-
upperBound를 2bitLength - 1로 둔다.
-
-
그렇지 않으면:
-
lowerBound를 -(2bitLength - 1)로 둔다.
-
upperBound를 2bitLength - 1 - 1로 둔다.
-
-
x가 -0이면, x를 +0으로 설정한다.
-
x가 NaN이면, +0을 반환한다.
-
x를 min(max(x, lowerBound), upperBound)로 설정한다.
-
x를 가장 가까운 integer로 round하되, 두 integer 사이의 halfway에 있으면 even integer를 선택하고, -0보다 +0을 선택한다.
-
x를 반환한다.
참고: 이는 [WEBIDL]의 정의를 기반으로 하며 다음 차이가 있다: 64-bit integers는 특별하게 취급되지 않고, input x는 abstract number이며, clamping은 항상 수행된다.
9.3. 기타
[INFRA]에 definition이 제공되면 이를 제거한다. [whatwg/infra Issue #664]
10. 예
constant1 ---+
+--- Add ---> intermediateOutput1 ---+
input1 ---+ |
+--- Mul---> output
constant2 ---+ |
+--- Add ---> intermediateOutput2 ---+
input2 ---+
다음 code는 graph를 구현한다:
// 4 dimensions의 tensors를 사용한다. const TENSOR_SHAPE= [ 1 , 2 , 2 , 2 ]; const TENSOR_SIZE= 8 ; const context= await navigator. ml. createContext(); const builder= new MLGraphBuilder( context); // MLOperandDescriptor object를 생성한다. const desc= { dataType: 'float32' , shape: TENSOR_SHAPE}; // constant1은 값 0.5를 가진 constant MLOperand이다. const constantBuffer1= new Float32Array( TENSOR_SIZE). fill( 0.5 ); const constant1= builder. constant( desc, constantBuffer1); // input1은 input MLOperands 중 하나이다. 그 값은 execution 전에 설정된다. const input1= builder. input( 'input1' , desc); // constant2는 값 0.5를 가진 또 다른 constant MLOperand이다. const constantBuffer2= new Float32Array( TENSOR_SIZE). fill( 0.5 ); const constant2= builder. constant( desc, constantBuffer2); // input2는 또 다른 input MLOperand이다. 그 값은 execution 전에 설정된다. const input2= builder. input( 'input2' , desc); // intermediateOutput1은 첫 번째 Add operation의 output이다. const intermediateOutput1= builder. add( constant1, input1); // intermediateOutput2는 두 번째 Add operation의 output이다. const intermediateOutput2= builder. add( constant2, input2); // output은 Mul operation의 output MLOperand이다. const output= builder. mul( intermediateOutput1, intermediateOutput2);
11. 오퍼레이터 에뮬레이션
이 섹션은 비규범적이다.
다른 neural network inference APIs에 존재하는 operations는 WebNN에 존재하는 operations를 사용해 emulated할 수 있는 경우가 많다.
11.1. squeeze
squeeze operation은
size 1인 input의 모든 지정된 dimensions가 제거된 tensor를 반환한다. 이는 다음과 같이
reshape()
operation을 사용해 일반적으로 구현할 수 있다:
function squeeze( builder, input, axes) { if ( ! axes) axes= []; if ( ! axes. length) input. shape. forEach(( item, i) => { axes. push( i); }); const shape= Array. from ( input. shape); for ( let axisof axes. sort(). reverse()) if ( axis< shape. length&& shape[ axis] == 1 ) shape. splice( axis, 1 ); return builder. reshape( input, shape); }
11.2. unsqueeze
11.3. flatten
flatten operation은
input을 one-dimensional tensor로 reshape한다. 이는 다음과 같이 reshape()
operation을 사용해 일반적으로 구현할 수 있다:
function flatten( builder, input, axis) { if ( axis> input. shape. length) return input; const before= axis. slice( 0 , axis). reduce(( a, b) => a* b, 1 ); const after= axis. slice( axis, input. shape. length). reduce(( a, b) => a* b, 1 ); return builder. reshape( input, [ before, after]); }
12. 부록
12.1. MLOperandDataType
및 ArrayBufferView
compatibility
MLOperandDataType
| ArrayBufferView
|
|---|---|
float32
| Float32Array
|
float16
| Float16Array
|
int64
| BigInt64Array
|
uint64
| BigUint64Array
|
int32
| Int32Array
|
uint32
| Uint32Array
|
int8
| Int8Array
|
uint8
| Uint8Array
|
Float16Array는
설계가 완료되었음을 나타내는 ECMA Stage 3에 있다.
native implementations에 앞서 이 type을 enable하려는 implementers는 Uint16Array를
통해 raw bits를 전달함으로써 이 type을 emulate할 수 있다.
[Issue webnn#373]
13. 감사의 말
이 명세는 Android Neural Networks API C API의 concept들을 따른다.
use cases에 대해 Tomoyuki Shimizu, Ningxin Hu, Zhiqiang Yu 및 Belem Zhang에게 감사한다.
API 명세에 기여해 준 Nikhil Thorat, Daniel Smilkov, Ganesan Ramalingam, Rafael Cintron 및 Benjamin Poulain에게 감사한다.
web architecture fit, design consistency 및 developer ergonomics에 대해 이 명세를 검토해 준 Sangwhan Moon 및 W3C Technical Architecture Group에게 감사한다.
algorithms를 추가하고 이 명세를 탐색하기 즐거운 경험으로 만들어 준 Zoltan Kis에게 감사한다. 명세를 modern editorial conventions에 맞춰 준 Joshua Bell에게 감사한다. 세심한 review와 comments에 대해 Ningxin Hu, Lisha Guo, Shiyi Zou, Mingming Xu, Junwei Fu, Bruce Dai 및 Bin Miao에게 감사한다.
privacy and security review 및 feedback에 대해 W3C Privacy Interest Group에게 감사한다.
security review 및 questions에 대해 Alex Gough 및 Chrome Security team에게 감사한다.
ONNX로부터의 practical guidelines 및 learnings를 공유해 준 Michal Karzynski에게 감사한다.
feedback 및 privacy considerations에 대해 Kaustubha Govind 및 Chrome privacy reviewers에게 감사한다.
Chromium implementation review 및 feedback에 대해 Jiewei Qian에게 감사한다.
transformer support에 대한 recommendation을 조사하고 제공한 작업에 대해 Dwayne Robinson, Joshua Lochner 및 Wanming Lin에게 감사한다. operator conformance 및 web-platform-tests implementation의 reviews를 제공해 준 Dwayne과 Wanming에게도 추가로 감사한다.
web-platform-tests가 명세와 함께 발전하도록 계속 기여해 준 Feng Dai에게 감사한다.
reviews 및 suggestions에 대해 Fuqiao Xue 및 W3C Internationalization Activity에게 감사한다.
14. 변경 사항
이 섹션은 비규범적이다.
이 섹션은 이 명세의 이전 major publication 이후의 변경 사항을 Classes of Changes 관점에서 문서화한다.
Candidate Recommendation Snapshot 2024년 4월 11일과 2026년 1월 22일 사이의 상세 변경 사항
새 기능(class 4)
- dequantizeLinear, quantizeLinear 및 attention operations를 포함한 새 operators로 operator set "wave 3" 확장 (#805)
- WebNN과 WebGPU 사이의 buffer sharing 및 여러 MLGraphs 간 reuse를 위한 인터페이스인 MLTensor API 추가 (#787)
- NaN 및 infinite values를 검사하는 새 element-wise operators인 isNaN 및 isInfinite operators 추가 (#858)
- banker’s rounding을 사용하는 새 rounding operator인 roundEven operator 추가 (#859)
- ML accelerators를 선택하기 위한 simple mechanism인 accelerator selection mechanism 추가 (#895)
- WebNN availability를 window 및 dedicated worker를 넘어 확장하기 위해 shared workers 및 service workers에 WebNN API 노출 (#823)
- 더 diagnosable한 error messages를 위한 optional operator labels 추가 (#742)
- 모든 type의 numeric inputs를 지정하기 위한 unified type인 MLNumber 도입 (#647)
- support limits에서 rank ranges를 지정할 수 있도록 opSupportLimits()에 rankRange 추가 (#828)
- rankRange support를 output tensors로 확장하기 위해 op output tensors에 rankRange 지원 (#857)
Neural Processing Unit(NPU) device type인 MLDeviceType npu 추가 (#696)- 이 기능은 device selection을 단순화하기 위해 이전 publication 이후 추가되었다가 제거되었다. #809 참조- MLContext와 MLGraph에 destroy() methods 추가, context loss behavior 및 error reporting 지정 (#744)
- softmax operation에 optional axis parameter 추가 (#649)
- output data type 지정을 지원하기 위해 argmin/argmax에 outputDataType 추가 (#730)
- resample2d가 임의 axes에서 동작하도록 일반화하기 위해 resample2d에 arbitrary axes 허용 (#752)
- 8-bit integer types를 지원하도록 resample을 확장하기 위해 Resample data type uint8/int8 추가 (#891)
- conv2d 및 pool2d operations의 operand layout support 단순화, pool2d에서 MLRoundingType 제거, layout support 단순화 (#770)
- backend limits에 더 잘 맞도록 padding options 제한 (#843)
새 기능을 추가하지 않는 기타 변경 사항(class 3)
- MLTensor API를 위해 MLContext.compute() method 제거 (#795)
- device type enumeration을 제거하여 device selection을 단순화하기 위해 MLDeviceType 제거 (#809)
- MLOperand methods를 readonly attributes로 변환하고 dataType() 및 shape()를 methods에서 attributes로 변경 (#774)
- MLOperandDescriptor.shape를 required property로 만듦 (#764)
- build method를 single invocation으로 제한하기 위해 MLGraphBuilder.build()가 한 번만 호출될 수 있도록 허용 (#717)
- sequence-based constant creation을 제거하기 위해 constant()의 fillSequence overload 제거 (#656)
- consistency를 위해 parameters를 재정렬하도록 scalar constant() operand method의 parameters 교체 (#650)
- argmin/argmax API를 단순화하기 위해 argmin/argmax selectLastIndex parameter 제거 (#722)
- API 전체의 consistency를 위해 cast/constant parameter type을 dataType으로 rename (#888)
- recurrent network activations에 더 specific한 type을 위해 MLActivation을 MLRecurrentNetworkActivation으로 replace (#718)
- 더 나은 Unicode support를 위해 DOMString을 USVString으로 변경 (#715)
- clarity를 위해 where의 parameter names rename (#719)
- consistency를 위해 MLLstmCellSupportLimits의 member output을 outputs로 rename (#757)
- proper promise rejection을 위해 destroyed MLTensor에서 진행 중인 operations에 대한 promises reject (#799)
- data type validation rules를 가능하게 하기 위해 operations의 operand data type constraints 지정 (#646)
- validation improvements를 위해 여러 ops에 누락된 validation steps 추가 (#820)
- array operations에 대한 validation을 향상시키기 위해 pad(), slice(), split()에 누락된 validation 추가 (#690)
- recurrent network validation을 개선하기 위해 GRU/LSTM validation 단순화, 수정 및 추가 (#659)
- GRU 및 LSTM operators의 hidden size 검증 (#644)
- transposed convolution에 대한 더 엄격한 validation을 위해 convTranspose2d의 output padding restriction 검증 (#631)
- gather operation validation 개선 (#642)
- 일반 validation improvements (#643)
- resource validation 개선 (#622)
- buffer transfers에 대한 errors를 적절히 처리하기 위해 MLNamedArrayBufferViews transfer algorithm의 error handling 정의 (#723)
- dimension valid range를 signed integer로 update (#738)
- dimension validity를 formalize하기 위해 "valid dimension" concept 도입 (#641)
- object creation에 대한 proper realm handling을 위해 object creation에서 realm 지정 보장 (#810)
- division operator rounding 명확화 (#909)
- pad scalar inconsistency 수정 (#894)
- split op에 대한 opSupportLimits error 수정 (#776)
- softmax() axis argument에서 proper range enforcement를 위해 EnforceRange 사용 (#746)
- conv2d algorithms에 inputShape의 missing definitions 추가 (#680)
- unidirectionally broadcast shapes steps 수정 (#663)
- buffer transferring이 실패할 경우 compute() promise rejection behavior 수정 (#639)
- 64-bit integer types로 ArrayBufferView compatibility table update (#698)
문서 해석에 기능적으로 영향을 주지 않는 변경 사항(class 2)
- validation에 대한 systematic approach를 위해 operand data type 및 rank validation을 table-driven으로 만듦 (#657)
- operators by category의 non-normative table 추가 (#868)
- 서로 다른 data types 사이의 cast() op behavior 명확화 (#726)
- resample2d의 interpolation algorithms 명확화 (#816)
- edge cases를 명확히 하기 위해 empty axes 및 scalar input을 가진 reduction 명확화 (#741)
- no-op graphs에 대한 note 추가 (#665)
- reduction operation behavior를 명확히 하기 위해 reduction ops의 keepDimensions에 대한 note 추가 (#648)
- emulation documentation 재구성 (#598)
- reduceLogSum, reduceLogSumExp 및 reduceSumSquare에 대한 decompositions 추가 (#637)
- clamp() minValue == maxValue 관련 interop issues에 대한 obsolete note 제거 (#684)
- specification boilerplate metadata information update (#769)
- architectural resource contention considerations 추가 (#765)
- Unicode에 대한 security considerations 추가 (#851)
- computation control-flow attacks에 대한 security consideration 추가 (#725)
- privacy considerations 개정 (#890)
- opSupportLimits() fingerprinting에 대한 privacy considerations 추가 (#881)
- accessibility considerations 추가 (#869)
- label usage에 관한 internationalization note 추가 (#841)
Editorial(class 2)
- 여러 editorial improvements (#834)
- 여러 style 및 wording tweaks (#797)
- Grammar 및 spelling corrections (#782)
- helpers algorithms로 specification steps 단순화 (#737)
- type references 개선 (#735)
- WebIDL transferable definition 참조 (#732)
- terminology usage 개선을 위해 prose에서 "sequence" 피하기 (#729)
- linting 및 validation 강화를 위해 algorithm steps 검증 logic 개선 (#727)
- cross-references 개선을 위해 method argument definitions 연결 (#721)
- organization 개선을 위해 불필요한 subsections 제거 (#711)
- adjective가 의도된 경우 "empty"가 아니라 "is empty"에 link (#708)
- 이 명세의 authoring 및 review를 쉽게 하기 위한 utilities 추가 (#702)
- "transferred" cross-reference 수정 (#679)
- authoring experience 개선을 위해 "generically emulated" text를 macro로 만듦 (#638)
- 'backward' 및 'both' directions에 의한 LSTM emulation error 수정 (#802)
- 'backward' 및 'both' directions에 의한 GRU emulation error 수정 (#803)
- decompositions의 typos/JS errors 수정 (#699)