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)
メソッドの手順は次のとおりである。
-
globalを、thisの関連グローバルオブジェクトとする。
-
tensor.
[[context]]がthisでない場合、TypeErrorで rejectされた、 realm内の新しい promiseを返す。 -
tensor.
[[isDestroyed]]がtrueである場合、TypeErrorで rejectされた、 realm内の新しい promiseを返す。 -
tensor.
[[descriptor]].readableがfalseである場合、TypeErrorで rejectされた、 realm内の新しい promiseを返す。 -
outputDataおよびtensor.
[[descriptor]]が与えられて記述子でバッファを検証する結果がfalseを返す場合、TypeErrorで rejectされた、 realm内の新しい promiseを返す。 -
promiseをrealm内の新しい promiseとする。
-
promiseをtensor.
[[pendingPromises]]へ 追加する。 -
次の手順をtensor.
[[context]].[[timeline]]へ エンキューする。-
これらの手順を実行する。ただし、thisがlostであるときは中止する。
-
それが失敗した場合、次の手順を実行するため、globalとともにMLタスクをキューに入れる。
-
tensor.
[[pendingPromises]]から promiseを削除する。 -
promiseを"
UnknownError"DOMExceptionで Rejectし、 これらの手順を中止する。
-
-
それ以外の場合、次の手順を実行するため、globalとともにMLタスクをキューに入れる。
-
tensor.
[[pendingPromises]]から promiseを削除する。 -
outputDataがdetachされている場合、 promiseを
TypeErrorで rejectし、 これらの手順を中止する。注記: 上記の記述子でバッファを検証するは、 outputDataがdetachされている場合に失敗するが、その手順とこの手順の間に outputDataがdetachされる可能性がある。
-
bytesをoutputDataへ書き込む。
-
-
中止された場合、globalとともにMLタスクをキューに入れ、 promiseを"
InvalidStateError"DOMExceptionで rejectする。
-
-
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]]が与えられて記述子でバッファを検証する結果がfalseを返す場合、TypeErrorを throwする。 -
bytesを、inputDataが与えられてバッファソースが保持するバイトのコピーを取得する結果とする。
-
Assert: bytesの長さは、tensor.
[[descriptor]]の バイト長と等しい。 -
次の手順をtensor.
[[context]].[[timeline]]へ エンキューする。-
これらの手順を実行する。ただし、thisがlostであるときは中止する。
-
bytesをtensor.
[[data]]へコピーする。テンソルへの書き込み中にエラーを報告する仕組みを追加する。 [Issue #778]
-
-
注記: dispatch()と同様に、
writeTensor()自体は、書き込みが完了したことを示すシグナルを提供しない。テンソルの内容を調べるために、
呼び出し側はテンソルを読み戻した結果をawaitできる。
8.3.7.
opSupportLimits()
opSupportLimits()は、
実装間で演算子レベルにおいて異なるサポートレベルを公開する。WebNN APIの利用者は、
各ターゲットプラットフォームに配備する最適なモデルアーキテクチャを決定するために、opSupportLimits()を
使用して機能サポートレベルを調べることが推奨される。
注記: opSupportLimits()
APIは、ブラウザーフィンガープリンティングのために追加のエントロピーを提供することを意図していない。現在の実装では、
この機能サポート情報はOSおよびブラウザーバージョンだけから推論できる。将来の実装の多様性がそれを正当化する場合、
このAPIにより、将来の実装は、エントロピーを低減するためWebGPUと同様に能力をバケット化するなど、
新しいプライバシー緩和策を追加できる。
フィンガープリンティングに関する考慮事項の追加の議論については、§ 5 プライバシーの考慮事項を参照。
8.3.7.1. MLOpSupportLimits
辞書
MLOpSupportLimitsは
次のトップレベルメンバーを持つ。これらに加えて、各演算子には、そのビルダーメソッドで定義される対応するメンバーがある。
dictionary {MLOpSupportLimits MLInputOperandLayout preferredInputLayout ; [EnforceRange ]unsigned long long maxTensorByteLength ;MLTensorLimits input ;MLTensorLimits constant ;MLTensorLimits output ; };
preferredInputLayout, 型はMLInputOperandLayout-
conv2d()など、 レイアウト依存演算子に対する推奨入力レイアウト。 maxTensorByteLength, 型はunsigned long long-
テンソルのサポートされる最大長(バイト単位)。
input, 型はMLTensorLimitsconstant, 型はMLTensorLimitsoutput, 型はMLTensorLimits
8.3.7.2. MLRankRange
辞書
dictionary {MLRankRange unsigned long min ;unsigned long max ; };
min, 型はunsigned long-
サポートされる最小ランク。
max, 型はunsigned long-
サポートされる最大ランク。
8.3.7.3. MLTensorLimits
辞書
typedef sequence <MLOperandDataType >;MLDataTypeList dictionary {MLTensorLimits MLDataTypeList dataTypes ;MLRankRange rankRange ; };
dataTypes, 型はMLDataTypeList-
サポートされるデータ型。
rankRange, 型はMLRankRange-
サポートされる最小および最大ランク。
8.3.7.4. MLBinarySupportLimits
辞書
dictionary {MLBinarySupportLimits MLTensorLimits a ;MLTensorLimits b ;MLTensorLimits output ; };
a, 型はMLTensorLimits-
aオペランド用の
MLTensorLimits。 b, 型はMLTensorLimits-
bオペランド用の
MLTensorLimits。 output, 型はMLTensorLimits-
出力オペランド用の
MLTensorLimits。
8.3.7.5. MLSingleInputSupportLimits
辞書
dictionary {MLSingleInputSupportLimits MLTensorLimits input ;MLTensorLimits output ; };
input, 型はMLTensorLimits-
入力オペランド用の
MLTensorLimits。 output, 型はMLTensorLimits-
出力オペランド用の
MLTensorLimits。
8.3.8.
destroy()
destroy()
メソッドは、コンテキストに関連付けられたすべてのリソースを解放するために呼び出すことができる。未完了の計算要求、
およびMLTensorの
作成/読み取り/書き込み要求は失敗する。
destroy()メソッドの手順は次のとおりである。
8.3.9. エラー
ユーザーエージェントが、MLContextが
要求を満たすために利用できなくなったと判断した場合、そのためのコンテキスト喪失手順を実行しなければならない。
MLContext
contextに対するコンテキスト喪失
手順は次のとおりである。
-
globalを、contextの関連グローバルオブジェクトとする。
-
次の手順を実行するため、globalとともにMLタスクを キューに入れる。
MLContext
contextを、DOMString
messageでloseするには:
-
infoを新しい
MLContextLostInfoとする。 -
info.
messageをmessageに設定する。 -
graph.
[[context]]がthisと等しい各MLGraphgraphについて: -
tensor.
[[context]]がthisと等しい各MLTensortensorについて:
message, 型はDOMString-
発生したエラーに関する情報を提供する実装定義のメッセージ。
MLContextは、
その[[lost]]
Promise
がsettledしている場合、lostである。
8.4. MLGraph
インターフェイス
MLGraph
インターフェイスは、コンパイル済み計算グラフを表す。コンパイル済みグラフは、一度構築されると不変であり、
その後変更できない。
[SecureContext ,Exposed =(Window ,Worker )]interface {MLGraph undefined destroy (); };
MLGraphは
次の内部スロットを持つ。
[[context]]、型はMLContext[[inputDescriptors]]、型は record<USVString,MLOperandDescriptor>-
この
MLGraphのすべての 入力MLOperandについて、 入力MLOperandの名前を そのMLOperandDescriptorに対応付ける。 [[outputDescriptors]]、型は record<USVString,MLOperandDescriptor>-
この
MLGraphのすべての 出力MLOperandについて、 出力MLOperandの名前を そのMLOperandDescriptorに対応付ける。 [[implementation]]-
ユーザーエージェントにより提供される基盤実装。
[[isDestroyed]]、型はboolean-
MLGraph.destroy()メソッド手順が実行されたかどうか。いったん破棄されると、MLGraphはもはや使用できない。
8.4.1. destroy()
destroy()
メソッドは、グラフに関連付けられたすべてのリソースを解放するために呼び出すことができる。
destroy()メソッドの手順は次のとおりである。
-
this.
[[isDestroyed]]がtrueである場合、これらの手順を中止する。 -
this.
[[isDestroyed]]をtrueに設定する。 -
このグラフが所有するリソースを解放可能としてマークするために、this.
[[context]].[[timeline]]上にタスクをキューに入れる。
注記: このグラフを使用してこれ以上ワークロードをキューに入れることはできないため、 実装は、このグラフを使用して以前に送信されたすべてのワークロードが完了した後、このグラフに関連付けられた追加のリソース割り当てを解放できる。
8.5. MLOperandDescriptor
辞書
MLOperandDescriptorは、
オペランドの形状(次元)およびデータ型を記述する。これはMLGraphの入力および
定数を記述するために使用され、各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-
オペランドのデータ型。
shape, 型はsequence<[EnforceRange] unsigned long>-
オペランドの次元のリスト。スカラーオペランドの場合は空である。
MLOperandDescriptor
Aは、A.dataTypeが
B.dataTypeと等しく、
かつA.shapeが
B.shapeと
等しい場合、MLOperandDescriptor
Bと等しい。
MLOperandDataType
dataTypeおよびリストshapeが与えられたとき、MLOperandDescriptorを
作成するには、次の手順を実行する。
-
descriptorを新しい
MLOperandDescriptorとする。 -
descriptor.
dataTypeをdataTypeに設定する。 -
descriptorを返す。
MLOperandDescriptor
descのバイト長は、次の手順により返される値である。
MLOperandDescriptor
descの要素数は、次の手順により返される値である。
妥当な次元は、
0より大きく、longの範囲内にある整数である。
実装はより小さな上限を課してもよい。
妥当なテンソル 数は、0より大きく8192以下の整数である。実装はより小さな上限を課してもよい。
サイズ0の次元は サポートされるべきか? [Issue #391]
MLOperandDescriptor
descriptorが与えられたとき、次元をチェックするには、次の手順を実行する。
8.6. MLOperand
インターフェイス
MLOperandは、
演算の一部を完全に合成された演算へ合成した結果として構築される、中間グラフを表す。
例えば、MLOperandは、
演算に供給される定数、または複数の定数を1つの演算へ結合した結果を表すことができる。
§ 7 プログラミングモデルも参照。
[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
は次の内部スロットを持つ。
MLOperandの
dataTypeは、その[[descriptor]].dataTypeである。
MLOperandの
shapeは、その[[descriptor]].shapeである。
MLOperandの
rankは、そのshapeのサイズである。
dataTypeの取得手順は、
thisのdataTypeを返すことである。
shapeの取得手順は、
thisのshapeを返すことである。
[[builder]]
オブジェクトは、MLGraphBuilder()
コンストラクターによりMLContext
オブジェクトに束縛されるため、MLOperandも
常に同じMLContext
オブジェクトに束縛される。
演算がMLOperandDataTypeの
サブセットのみをサポートする場合、位置引数とオプションの両方を含む、演算の各入力オペランドに対する許可されるデータ
型は、MLOperandDataTypeの
明示的なリスト、またはオペランドのdataTypeが別の入力オペランドのdataTypeと同じでなければならないという制約、または任意のMLOperandDataTypeを
許可する任意として与えられる。
実装は、指定されているより少ないデータ型をオペランドに対してサポートしてもよい。これは、
MLContext上のopSupportLimits()
メソッドを使用し、演算に対応するメンバーのdataTypes
値を調べることにより、各演算について照会できる。
各演算子に対して サポートされなければならないデータ型のサブセットを指定すべきか?
演算が特定のrankを持つ入力オペランドを必要とする場合、位置引数とオプションの両方を含む、 演算の各入力オペランドに対する許可されるランクは、明示的なランク(例: 1)、または任意の次元数を許可するN、または別のオペランドと 同じとして与えられる。より具体的な制約も一般的であり、例えば入力オペランドの形状が 別の入力オペランドに対して単方向にブロードキャスト可能でなければならない場合、または双方向にブロードキャスト可能でなければならない場合がある。 これらの場合、許可される ランクは範囲として列挙され、具体的な検証は演算内の手順として与えられる。
実装は、オペランドのrankに対して、指定されているより制限された下限および/または上限を課してもよい。
これは、MLContext上のopSupportLimits()
メソッドを使用し、演算に対応するメンバーのrankRange.min
およびrankRange.max
値を調べることにより、各演算について照会できる。
MLOperatorOptions
は次のメンバーを持つ。
label, 型はUSVString、デフォルトは""-
MLOperandを作成するMLGraphBuilderメソッドを使用して演算子が作成されるときに任意で提供される。 実装はこの値を使用して演算子のラベルを初期化してもよい。
注記: ラベルは自然言語文字列であることを意図していない。
これは、"mul#1234"のような、変数名またはエラーコードに類似した言語非依存の識別子である。
注記: 実装は、開発者から提供されたlabelを
使用して、グラフ構築中の同期エラー、および非同期build()
メソッド中に発生するエラーの両方を含め、エラーメッセージを強化しデバッグ容易性を向上させることが推奨される。
デバッグツール、ログ、またはエラーメッセージで、開発者がlabel
を通じて提供したラベルを表示するとき、実装は出力をサニタイズして、悪意あるUnicodeシーケンスの注入などの
セキュリティリスクを防止すべきである(例: 双方向テキスト
スプーフィング [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.[[builder]]
がbuilderであればtrueを返し、そうでなければfalseを返す。
8.6.1.1.
MLNumber
MLNumberは、64ビット整数型("uint64"
および"int64")と
32ビット浮動小数点("float32")の
両方を含む、任意のMLOperandDataTypeであり得る
MLOperandに対する数値オプションの型を指定するときに使用される。
実装は、対応するMLOperandDataTypeに従って値を処理する。
例えば、clamp(input, options)が、
dataTypeが"uint32"である
MLOperandで呼び出された場合、
MLNumber
パラメーターは明示的にunsigned longへキャストされる。
bigint
と数値型の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] 범위에 있어야 한다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1에서 N까지 |
| output | "int32",
"int64"
| N |
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| 1에서 N까지 |
mean
| input과
같음
| 1 |
variance
| input과
같음
| 1 |
scale
| input과
같음
| 1 |
bias
| input과
같음
| 1 |
| output | input과
같음
| input과
같음
|
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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, mean, variance, options.
scale(그것이 존재하는 경우), 및 options.bias(그것이 존재하는 경우) 중 하나가 주어졌을 때 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으로 캐스팅한 결과로 설정한다. -
그래프 연결 만들기:
-
operator를 input, mean, variance 및 options가 주어진 "batchNormalization" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | any | input과
같음
|
MLOpSupportLimits는
cast()에
대해 다음 멤버를 가진다.
cast, 타입은 MLSingleInputSupportLimits-
cast()오퍼레이터에 대한 지원 제한.
MLOperandDataType들
사이의 캐스팅은 다음 표에 따라, 일부 경우에는 지정되어 있고 다른 경우에는 구현
정의이다.
| 대상 타입 입력 타입 |
"float32",
"float16"
|
"int32",
"uint32",
"int64",
"uint64",
"int8",
"uint8"
|
|---|---|---|
"float32",
"float16"
|
범위 안이면, 가장 가까운 표현 가능한 값.
범위를 벗어나면, +/-Infinity. |
범위 안이면, truncation됨.
범위를 벗어나면, 구현 정의. |
"int32",
"uint32",
"int64",
"uint64",
"int8",
"uint8"
|
범위 안이면, 가장 가까운 표현 가능한 값.
범위를 벗어나면, +/-Infinity. |
범위 안이면, 같은 값.
범위를 벗어나면, signed 타입에는 two’s complement를 가정하여 최하위 N비트를 대상 타입으로 재해석한다. |
참고: 예를 들어 "int8"에서
"uint8"로
-1을 캐스팅하면 255가 산출되도록 지정되어 있다. 그러나 "float32"에서
"uint8"로
-1을 캐스팅하는 것은 구현 정의이다.
cast(input, dataType, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
dataType이 (이 표에 따른) output tensor의 허용되는 데이터 타입이 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
operator를 dataType 및 options가 주어진 "cast" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | input과
같음
| input과
같음
|
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를 가진다.
해당 차원의 크기는 같은 차원의 모든 입력 크기의 합으로 계산된다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
inputs의
items
| any | 1에서 N까지 |
| output | inputs의
items와
같음
| inputs의
items와
같음
|
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
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| 4 |
filter
| input과
같음
| 4 |
bias
| input과
같음
| 1 |
| output | input과
같음
| 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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, filter, 및 options.
bias(그것이 존재하는 경우) 중 하나가 주어졌을 때 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
filter의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그렇지 않고, options.
dilations의 size가 2가 아니면,TypeError를 throw한다. -
출력 shape 계산하기:
-
inputShape를 input의 shape로 둔다.
-
options.
inputLayout에 대해 switch한다: -
filterShape를 filter의 shape로 둔다.
-
options.
filterLayout에 대해 switch한다:"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 size를 계산한 결과로 둔다. -
outputHeight를 floor( outputHeight )로 설정한다.
-
outputWidth를 floor( outputWidth )로 설정한다.
-
outputHeight 또는 outputWidth 중 하나라도 유효한 차원이 아니면,
TypeError를 throw한다. -
options.
inputLayout에 대해 switch한다: -
desc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options 및 filter가 주어진 "conv2d" 연산에 대한 오퍼레이터로 둔다.
-
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
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| 4 |
filter
| input과
같음
| 4 |
bias
| input과
같음
| 1 |
| output | input과
같음
| 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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, filter, 및 options.
bias(그것이 존재하는 경우) 중 하나가 주어졌을 때 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한다.
-
-
출력 shape 계산하기:
-
inputShape를 input의 shape로 둔다.
-
options.
inputLayout에 대해 switch한다: -
filterShape를 filter의 shape로 둔다.
-
options.
filterLayout에 대해 switch한다: -
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에 대해 switch한다: -
desc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options 및 filter가 주어진 "convTranspose2d" 연산에 대한 오퍼레이터로 둔다.
-
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 ; };
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16",
"int32",
"uint32",
"int64",
"uint64"
| 1에서 N까지 |
| output | input과
같음
| input과
같음
|
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로 계산한다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
a
| any | N |
b
| a와
같음
| N |
| output | a와
같음
| N |
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
a
| 연산 단계의 일부로 지정됨 | N |
b
| a와
같음
| N |
| output | "uint8"
| N |
MLLogicalNotSupportLimits는
다음 멤버를 가진다.
a, 타입은 MLTensorLimits-
a 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
element-wise 논리 연산에 대해 다음 멤버를 가진다.
equal, 타입은 MLBinarySupportLimits-
equal()오퍼레이터에 대한 지원 제한. notEqual, 타입은 MLBinarySupportLimits-
notEqual()오퍼레이터에 대한 지원 제한. greater, 타입은 MLBinarySupportLimits-
greater()오퍼레이터에 대한 지원 제한. greaterOrEqual, 타입은 MLBinarySupportLimits-
greaterOrEqual()오퍼레이터에 대한 지원 제한. lesser, 타입은 MLBinarySupportLimits-
lesser()오퍼레이터에 대한 지원 제한. lesserOrEqual, 타입은 MLBinarySupportLimits-
lesserOrEqual()오퍼레이터에 대한 지원 제한. logicalNot, 타입은 MLLogicalNotSupportLimits-
logicalNot()오퍼레이터에 대한 지원 제한. logicalAnd, 타입은 MLBinarySupportLimits-
logicalAnd()오퍼레이터에 대한 지원 제한. logicalOr, 타입은 MLBinarySupportLimits-
logicalOr()오퍼레이터에 대한 지원 제한. logicalXor, 타입은 MLBinarySupportLimits-
logicalXor()오퍼레이터에 대한 지원 제한. isNaN, 타입은 MLLogicalNotSupportLimits-
isNaN()오퍼레이터에 대한 지원 제한. isInfinite, 타입은 MLLogicalNotSupportLimits-
isInfinite()오퍼레이터에 대한 지원 제한.
-
equal: 두 입력 tensor의 값이 같은지 element-wise로 비교한다.
-
notEqual: 두 입력 tensor의 값이 같지 않은지 element-wise로 비교한다.
-
greater: 첫 번째 입력 tensor의 값이 더 큰지 element-wise로 비교한다.
-
greaterOrEqual: 첫 번째 입력 tensor의 값이 더 크거나 같은지 element-wise로 비교한다.
-
lesser: 첫 번째 입력 tensor의 값이 더 작은지 element-wise로 비교한다.
-
lesserOrEqual: 첫 번째 입력 tensor의 값이 더 작거나 같은지 element-wise로 비교한다.
-
logicalNot: 입력 tensor의 값을 element-wise로 0 또는 1 값으로 invert한다. 구체적으로, 입력 값이 non-zero이면 0으로 invert한다. 반대로 입력 값이 0이면 1로 invert한다.
-
logicalAnd: 두 입력 tensor의 논리 and를 element-wise로 계산하며, 모든 non-zero 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
logicalOr: 두 입력 tensor의 논리 or를 element-wise로 계산하며, 모든 non-zero 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
logicalXor: 두 입력 tensor의 논리 xor를 element-wise로 계산하며, 모든 non-zero 값을 true로 취급하고 0 또는 1의 element를 반환한다.
-
isNaN: 입력 tensor의 값이 유효하지 않은 numeric representation(NaN)인지 element-wise로 검사하고, NaN에는 1을, 그렇지 않으면 0을 반환한다.
-
isInfinite: 입력 tensor의 값이 infinity인지 element-wise로 검사하고, positive 또는 negative infinity에는 1을, 그렇지 않으면 0을 반환한다.
greaterOrEqual()
및 lesserOrEqual()
연산은 각각 logicalNot(),
lesser(),
및 greater()
연산으로 구현될 수 있지만(다시 말해 builder.greaterOrEqual(a, b)는
builder.logicalNot(builder.lesser(a, b))임), NaN 경우를 처리하고 성능상 이유로
이중 비교를 피하기 위해 별도로 정의된다.
string
op, MLOperand
a, 선택적 MLOperand
b, 및 MLOperatorOptions
options가 주어졌을 때 element-wise
논리 연산을 생성하려면, 다음 단계를 실행한다.
-
Assert: op는 "equal", "notEqual", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "logicalNot", "logicalAnd", "logicalOr", "logicalXor", "isNaN", "isInfinite" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 a가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
op가 "logicalNot", "logicalAnd", "logicalOr", "logicalXor" 중 하나이면:
-
op가 "isNaN", "isInfinite" 중 하나이면:
-
b가 전달되었으면:
-
그렇지 않으면:
-
descriptor를
"uint8"및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다. -
그래프 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 a 및 (b가 전달된 경우) b, 그리고 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
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와 같다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| 연산 단계의 일부로 지정됨 | N |
| output | input과
같음
| input과
같음
|
MLOpSupportLimits는
element-wise 단항 연산에 대해 다음 멤버를 가진다.
abs, 타입은 MLSingleInputSupportLimits-
abs()오퍼레이터에 대한 지원 제한. ceil, 타입은 MLSingleInputSupportLimits-
ceil()오퍼레이터에 대한 지원 제한. cos, 타입은 MLSingleInputSupportLimits-
cos()오퍼레이터에 대한 지원 제한. erf, 타입은 MLSingleInputSupportLimits-
erf()오퍼레이터에 대한 지원 제한. exp, 타입은 MLSingleInputSupportLimits-
exp()오퍼레이터에 대한 지원 제한. floor, 타입은 MLSingleInputSupportLimits-
floor()오퍼레이터에 대한 지원 제한. identity, 타입은 MLSingleInputSupportLimits-
identity()오퍼레이터에 대한 지원 제한. log, 타입은 MLSingleInputSupportLimits-
log()오퍼레이터에 대한 지원 제한. neg, 타입은 MLSingleInputSupportLimits-
neg()오퍼레이터에 대한 지원 제한. reciprocal, 타입은 MLSingleInputSupportLimits-
reciprocal()오퍼레이터에 대한 지원 제한. roundEven, 타입은 MLSingleInputSupportLimits-
roundEven()오퍼레이터에 대한 지원 제한. sin, 타입은 MLSingleInputSupportLimits-
sin()오퍼레이터에 대한 지원 제한. sign, 타입은 MLSingleInputSupportLimits-
sign()오퍼레이터에 대한 지원 제한. sqrt, 타입은 MLSingleInputSupportLimits-
sqrt()오퍼레이터에 대한 지원 제한. tan, 타입은 MLSingleInputSupportLimits-
tan()오퍼레이터에 대한 지원 제한.
-
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의 natural logarithm을 element-wise로 계산한다.
-
neg: input tensor의 numeric negative value를 element-wise로 계산한다.
-
reciprocal: input tensor의 reciprocal을 element-wise로 계산한다.
-
roundEven: input tensor를 halves to the nearest even value 방식으로 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, 선택적 list allowedDataTypes, 및 options가 주어졌을 때 element-wise
단항 연산을 생성하려면, 다음 단계를 실행한다.
-
Assert: op는 "abs", "ceil", "cos", "erf", "exp", "floor", "identity", "log", "neg", "reciprocal", "roundEven", "sin", "sign", "sqrt", "tan" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
allowedDataTypes가 주어졌고 그것이 input의 dataType을 contain하지 않으면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
output.
[[operator]]를 operator로 설정한다. -
operator의 input을 input으로 설정한다.
-
operator의 output을 output으로 설정한다.
-
-
output을 반환한다.
element-wise 단항 연산 알고리즘은 다음과 같이 element-wise 단항 연산을 생성하는 단계를 호출한다.
abs(input, options) 메서드
단계는 다음과 같다.
ceil(input, options) 메서드
단계는 다음과 같다.
-
output을 "ceil", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
cos(input, options) 메서드
단계는 다음과 같다.
-
output을 "cos", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
erf(input, options) 메서드
단계는 다음과 같다.
-
output을 "erf", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
exp(input, options) 메서드
단계는 다음과 같다.
-
output을 "exp", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
floor(input, options) 메서드
단계는 다음과 같다.
-
output을 "floor", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
identity(input, options)
메서드 단계는 다음과 같다.
-
output을 "identity", input, 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다.
-
output을 반환한다.
log(input, options) 메서드
단계는 다음과 같다.
-
output을 "log", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
neg(input, options) 메서드
단계는 다음과 같다.
reciprocal(input, options)
메서드 단계는 다음과 같다.
-
output을 "reciprocal", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
roundEven(input, options)
메서드 단계는 다음과 같다.
-
output을 "roundEven", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
sin(input, options) 메서드
단계는 다음과 같다.
-
output을 "sin", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
sign(input, options) 메서드
단계는 다음과 같다.
sqrt(input, options) 메서드
단계는 다음과 같다.
-
output을 "sqrt", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
tan(input, options) 메서드
단계는 다음과 같다.
-
output을 "tan", input, «
"float32","float16"», 및 options가 주어졌을 때 element-wise 단항 연산을 생성한 결과로 둔다. -
output을 반환한다.
sign()
연산의 동작은 다음과 같이 다른 연산을 사용하는 방식으로 일반적으로 에뮬레이션할 수 있지만, user
agent는 보통 더 효율적인 구현을 가진다. 기반 플랫폼이 어떤 연산을 직접 지원하지 않는 경우,
이 분해는 구현을 안내하는 템플릿으로 사용될 수 있다.
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "uint8",
"int8",
"uint32",
"int32"
| N |
scale
| "float32",
"float16"
| input과
같음
|
zeroPoint
| input과
같음
| input과
같음
|
| output | scale과
같음
| input과
같음
|
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 중 어느 하나가 주어졌을 때 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를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 outputDescriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, scale, zeroPoint, 및 options가 주어진 "dequantizeLinear" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
scale
| input과
같음
| input과
같음
|
zeroPoint
| "uint8",
"int8",
"uint32",
"int32"
| input과
같음
|
| output | zeroPoint와
같음
| input과
같음
|
MLOpSupportLimits는
quantizeLinear()에
대해 다음 멤버를 가진다.
quantizeLinear, 타입은 MLQuantizeDequantizeLinearSupportLimits-
quantizeLinear()오퍼레이터에 대한 지원 제한.
quantizeLinear(input, scale, zeroPoint, options)
메서드 단계는 다음과 같다.
-
this.
[[hasBuilt]]가 true이면, "InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, scale, 및 zeroPoint 중 어느 하나가 주어졌을 때 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를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 outputDescriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, scale, zeroPoint, 및 options가 주어진 "quantizeLinear" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | input과
같음
| input과
같음
|
MLOpSupportLimits는
elu()에
대해 다음 멤버를 가진다.
elu, 타입은 MLSingleInputSupportLimits-
elu()오퍼레이터에 대한 지원 제한.
elu(input, options) 메서드
단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "elu" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | input과
같음
| N |
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되는 입력 N-D tensor. -
indices:MLOperand. gather할 input 값들의 indices N-D tensor. 값들은"int32","uint32", 또는"int64"타입이어야 하며, N이axis가 index하는 input dimension의 size일 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 한다. negative index는 dimension의 끝에서부터 indexing함을 의미한다. -
options: 선택적MLGatherOptions. 연산의 선택적 매개변수.
반환: 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 안에 도입할 수 있다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1에서 N까지 |
indices
| "int32",
"uint32",
"int64"
| N |
| output | input과
같음
| N |
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되는 입력 N-D tensor. -
indices:MLOperand. gather할 input 값들의 indices N-D tensor. 값들은"int32","uint32", 또는"int64"타입이어야 하며, N이 options.axis가 index하는 input dimension의 size일 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 한다. negative index는 dimension의 끝에서부터 indexing함을 의미한다. -
options: 선택적MLGatherOptions. 연산의 선택적 매개변수.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1에서 N까지 |
indices
| "int32",
"uint32",
"int64"
| input과
같음
|
| output | input과
같음
| input과
같음
|
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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input 또는 indices 중 어느 하나가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
indices의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
input 또는 indices 중 어느 하나의 rank가 그 허용되는 rank가 아니면,
TypeError를 throw한다. -
axis를 options.
axis로 둔다. -
indicesShapeExpected를 input의 shape의 copy로 둔다.
-
indicesShapeExpected[axis]를 indices의 shape[axis]로 설정한다.
-
indices의 shape가 indicesShapeExpected와 같지 않으면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 input, indices, 및 options가 주어진 "gatherElements" 연산에 대한 오퍼레이터로 둔다.
-
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되는 입력 N-D tensor. -
indices:MLOperand. indices 배열은 input tensor 안의 전체 coordinate를 포함하며, 가장 오른쪽 dimension은 coordinate마다 dimension의 수를 보유한다. 따라서 shape [10,1]인 indices tensor는 10개의 single-axis indices를 보유하고, shape [4,3]은 4개의 3D coordinate indices를 보유한다. 값들은"int32","uint32", 또는"int64"타입이어야 하며, 각각은 N이 해당 input dimension의 size일 때 -N(포함)부터 N(제외)까지의 범위 안에 있어야 한다. negative index는 해당 dimension의 끝에서부터 indexing함을 의미한다. -
options: 선택적MLOperatorOptions. 연산의 선택적 매개변수.
반환: MLOperand.
input의
rank + indices의
rank - indices의
shape[-1] - 1과
같은 rank를 가지는
출력 N-D tensor.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1에서 N까지 |
indices
| "int32",
"uint32",
"int64"
| 1에서 N까지 |
| output | input과
같음
| N |
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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input 또는 indices 중 어느 하나가 주어졌을 때 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로 둔다.
-
0부터 indexableSize까지의 범위에서 끝값을 제외하고 각 index에 대해 반복한다:
-
indicesShape[index]를 outputShape에 append한다.
-
-
coordinateSize부터 inputRank까지의 범위에서 끝값을 제외하고 각 index에 대해 반복한다:
-
inputShape[index]를 outputShape에 append한다.
-
-
outputDesc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 outputDesc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, indices, 및 options가 주어진 "gatherND" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
gelu()에
대해 다음 멤버를 가진다.
gelu, 타입은 MLSingleInputSupportLimits-
gelu()오퍼레이터에 대한 지원 제한.
gelu(input, options) 메서드
단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "gelu" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
a
| "float32",
"float16"
| 2 |
b
| 같음 a
| 2 |
c
| 같음 a
| 0에서 2까지 |
| output | 같음 a
| 2 |
MLGemmSupportLimits는
다음 멤버를 가진다.
a, 타입은 MLTensorLimits-
a 피연산자에 대한
MLTensorLimits. b, 타입은 MLTensorLimits-
b 피연산자에 대한
MLTensorLimits. c, 타입은 MLTensorLimits-
c 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
gemm()에
대해 다음 멤버를 가진다.
gemm, 타입은 MLGemmSupportLimits-
gemm()오퍼레이터에 대한 지원 제한.
gemm(a, b, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 a 및 b 중 어느 하나가 주어졌을 때 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 순서를 reverse한다. -
options.
bTranspose가 true이면, shapeB의 item 순서를 reverse한다. -
-
그것이 shape « shapeA[0], shapeB[1] »로 unidirectionally broadcastable이 아니면,
TypeError를 throw한다. -
그것의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다.
-
-
desc를 a의 dataType 및 « shapeA[0], shapeB[1] »이 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 "gemm" 연산에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
| "float32",
"float16"
| 3 |
| 같음
| 3 |
| 같음
| 3 |
bias
| 같음
| 2 |
recurrentBias
| 같음
| 2 |
| 같음
| 3 |
| outputs[0] | 같음
| 3 |
outputs[1] if returnSequence
is true
| 같음
| 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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, weight, recurrentWeight, options.
bias(그것이 존재하면), options.recurrentBias(그것이 존재하면), 및 options.(그것이 존재하면) 중 어느 하나가 주어졌을 때 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이 유효한 dimension이 아니면,
TypeError를 throw한다.왜 hiddenSize * 6인가?
일부 기반 플랫폼은bias와recurrentBias를 concat한 단일 bias tensor에서 동작한다. 따라서 3 * hiddenSize + 3 * hiddenSize도 유효한 dimension이어야 한다. -
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를 생성한 결과로 둔다.
-
-
-
그래프 연결 만들기:
-
operator를 weight, recurrentWeight, steps, hiddenSize 및 options가 주어진 "gru" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
| "float32",
"float16"
| 2 |
| 같음
| 2 |
| 같음
| 2 |
bias
| 같음
| 1 |
recurrentBias
| 같음
| 1 |
| output | 같음
| 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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, weight, recurrentWeight, hiddenState, options.
bias(그것이 존재하면), 및 options.recurrentBias(그것이 존재하면) 중 어느 하나가 주어졌을 때 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이 유효한 dimension이 아니면,
TypeError를 throw한다.왜 hiddenSize * 6인가?
일부 기반 플랫폼은bias와recurrentBias를 concat한 단일 bias tensor에서 동작한다. 따라서 3 * hiddenSize + 3 * hiddenSize도 유효한 dimension이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
desc를 input의 dataType 및 « batchSize, hiddenSize »가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 weight, recurrentWeight, hiddenState, hiddenSize 및 options가 주어진 "gruCell" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
hardSigmoid()에
대해 다음 멤버를 가진다.
hardSigmoid, 타입은 MLSingleInputSupportLimits-
hardSigmoid()오퍼레이터에 대한 지원 제한.
hardSigmoid(input, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
options.
beta를 options.beta를 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "hardSigmoid" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
hardSwish()에
대해 다음 멤버를 가진다.
hardSwish, 타입은 MLSingleInputSupportLimits-
hardSwish()오퍼레이터에 대한 지원 제한.
hardSwish(input, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "hardSwish" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| 4 |
scale
| 같음 input
| 1 |
bias
| 같음 input
| 1 |
| output | 같음 input
| 4 |
MLNormalizationSupportLimits는
다음 멤버를 가진다.
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. scale, 타입은 MLTensorLimits-
scale 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
instanceNormalization()에
대해 다음 멤버를 가진다.
instanceNormalization, 타입은 MLNormalizationSupportLimits-
instanceNormalization()오퍼레이터에 대한 지원 제한.
instanceNormalization(input, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, options.
scale(그것이 존재하면), 및 options.bias(그것이 존재하면) 중 어느 하나가 주어졌을 때 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
epsilon을 options.epsilon을 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "instanceNormalization" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
scale
| 같음 input
| N |
bias
| 같음 input
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
layerNormalization()에
대해 다음 멤버를 가진다.
layerNormalization, 타입은 MLNormalizationSupportLimits-
layerNormalization()오퍼레이터에 대한 지원 제한.
layerNormalization(input, options)
메서드 단계는 다음과 같다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, options.
scale(그것이 존재하면), 및 options.bias(그것이 존재하면) 중 어느 하나가 주어졌을 때 false를 반환하면,TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
axes가 존재하지 않으면, options.axes를 새 list로 설정한다. input의 rank가 1보다 크면 1부터 input의 rank까지의 range(exclusive)로, 그렇지 않으면 빈 list로 설정한다. -
그렇지 않고, options.
axes가 중복 값을 포함하거나, 그 items 중 어느 하나가 0부터 input의 rank까지의 range(exclusive) 안에 없으면,TypeError를 throw한다. -
options.
epsilon을 options.epsilon을 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "layerNormalization" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
leakyRelu()에
대해 다음 멤버를 가진다:
leakyRelu, 타입은 MLSingleInputSupportLimits-
leakyRelu()오퍼레이터에 대한 지원 제한.
leakyRelu(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "leakyRelu" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
linear()에
대해 다음 멤버를 가진다:
linear, 타입은 MLSingleInputSupportLimits-
linear()오퍼레이터에 대한 지원 제한.
linear(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
options.
alpha를 options.alpha를 input의 dataType으로 casting한 결과로 설정한다. -
options.
beta를 options.beta를 input의 dataType으로 casting한 결과로 설정한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "linear" 연산에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
| "float32",
"float16"
| 3 |
| 같음
| 3 |
| 같음
| 3 |
bias
| 같음
| 2 |
recurrentBias
| 같음
| 2 |
peepholeWeight
| 같음
| 2 |
| 같음
| 3 |
initialCellState
| 같음
| 3 |
| outputs[0] | 같음
| 3 |
| outputs[1] | 같음
| 3 |
outputs[2] if returnSequence
is true
| 같음
| 4 |
MLLstmSupportLimits는
다음 멤버를 가진다:
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. weight, 타입은 MLTensorLimits-
weight 피연산자에 대한
MLTensorLimits. recurrentWeight, 타입은 MLTensorLimits-
recurrentWeight 피연산자에 대한
MLTensorLimits. bias, 타입은 MLTensorLimits-
bias 피연산자에 대한
MLTensorLimits. recurrentBias, 타입은 MLTensorLimits-
recurrentBias 피연산자에 대한
MLTensorLimits. peepholeWeight, 타입은 MLTensorLimits-
peepholeWeight 피연산자에 대한
MLTensorLimits. initialHiddenState, 타입은 MLTensorLimits-
initialHiddenState 피연산자에 대한
MLTensorLimits. initialCellState, 타입은 MLTensorLimits-
initialCellState 피연산자에 대한
MLTensorLimits. output0, 타입은 MLTensorLimits-
모든 output operands[0]에 대한
MLTensorLimits. output1, 타입은 MLTensorLimits-
모든 output operands[1]에 대한
MLTensorLimits. output2, 타입은 MLTensorLimits-
모든 output operands[2]에 대한
MLTensorLimits.
MLOpSupportLimits는
lstm()에
대해 다음 멤버를 가진다:
lstm, 타입은 MLLstmSupportLimits-
lstm()오퍼레이터에 대한 지원 제한.
lstm(input, weight, recurrentWeight, steps, hiddenSize, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, weight, recurrentWeight, options.
bias(그것이 존재하면), options.recurrentBias(그것이 존재하면), options.peepholeWeight(그것이 존재하면), options.(그것이 존재하면), 및 options.initialCellState(그것이 존재하면) 중 어느 하나가 주어졌을 때 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이 유효한 dimension이 아니면,
TypeError를 throw한다.왜 hiddenSize * 8인가?
일부 기반 플랫폼은bias와recurrentBias를 concat한 단일 bias tensor에서 동작한다. 따라서 4 * hiddenSize + 4 * hiddenSize도 유효한 dimension이어야 한다. -
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를 생성한 결과로 둔다.
-
-
-
그래프 연결 만들기:
-
operator를 weight, recurrentWeight, steps, hiddenSize 및 options가 주어진 "lstm" 연산에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
| "float32",
"float16"
| 2 |
| 같음
| 2 |
| 같음
| 2 |
| 같음
| 2 |
| 같음
| 2 |
bias
| 같음
| 1 |
recurrentBias
| 같음
| 1 |
peepholeWeight
| 같음
| 1 |
| outputs[0] | 같음
| 2 |
| outputs[1] | 같음
| 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가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, weight, recurrentWeight, hiddenState, cellState, options.
bias(그것이 존재하면), options.recurrentBias(그것이 존재하면), 및 options.peepholeWeight(그것이 존재하면) 중 어느 하나가 주어졌을 때 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이 유효한 dimension이 아니면,
TypeError를 throw한다.왜 hiddenSize * 8인가?
일부 기반 플랫폼은bias와recurrentBias를 concat한 단일 bias tensor에서 동작한다. 따라서 4 * hiddenSize + 4 * hiddenSize도 유효한 dimension이어야 한다. -
options.
recurrentBias가 존재하면: -
options.
peepholeWeight가 존재하면: -
options.
activations가 존재하면:-
activations를 options.
activations의 clone으로 둔다.
-
그렇지 않으면:
-
desc를 새
MLOperandDescriptor로 둔다. -
그래프 연결 만들기:
-
output0를 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
output1를 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
output을 list « output0, output1 »로 둔다.
-
operator를 weight, recurrentWeight, hiddenState, cellState, hiddenSize 및 options가 주어진 "lstmCell" 연산에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
a
| "float32",
"float16"
| 2 to N |
b
| 같음 a
| 2 or N |
| output | 같음 a
| 2 or N |
MLOpSupportLimits는
matmul()에
대해 다음 멤버를 가진다:
matmul, 타입은 MLBinarySupportLimits-
matmul()오퍼레이터에 대한 지원 제한.
matmul(a, b, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 a 및 b 중 어느 하나가 주어졌을 때 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 items)가 제거된 shapeA의 clone으로 둔다.
-
batchShapeB를 spatial dimensions(마지막 2 items)가 제거된 shapeB의 clone으로 둔다.
-
outputShape를 batchShapeA 및 batchShapeB를 bidirectionally broadcasting한 결과로 둔다. 그것이 failure를 반환하면,
TypeError를 throw한다. -
« rowsA, colsB »를 outputShape에 append한다.
-
desc를 a의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 "matmul" 연산에 대한 오퍼레이터로 둔다.
-
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
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| 같음 input
|
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)
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| operation steps의 일부로 지정됨 | 4 |
| output | 같음 input
| 4 |
MLOpSupportLimits는
pooling operations에 대해 다음 멤버를 가진다:
averagePool2d, 타입은 MLSingleInputSupportLimits-
averagePool2d()오퍼레이터에 대한 지원 제한. l2Pool2d, 타입은 MLSingleInputSupportLimits-
l2Pool2d()오퍼레이터에 대한 지원 제한. maxPool2d, 타입은 MLSingleInputSupportLimits-
maxPool2d()오퍼레이터에 대한 지원 제한.
// 'global' max pooling builder. maxPool2d( input);
string
op, MLOperand
input, MLPool2dOptions
options, 및 선택적 list allowedDataTypes가 주어졌을 때 pooling operation을 생성하려면, 다음 단계를 실행한다:
-
Assert: op는 "averagePool2d", "l2Pool2d", "maxPool2d" 중 하나이다.
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
allowedDataTypes가 주어졌고 그것이 input의 dataType을 contain하지 않으면,
TypeError를 throw한다. -
options.
layout에 대해 switch한다: -
options.
windowDimensions가 exist하지 않으면, options.windowDimensions를 « inputHeight, inputWidth »로 설정한다. -
options.
windowDimensions의 size가 2가 아니면,TypeError를 throw한다. -
options.
windowDimensions의 어떤 item이라도 0과 같으면,TypeError를 throw한다. -
options.
outputSizes가 존재하거나, 또는 options.padding이 exist하지 않으면, options.padding을 list « 0, 0, 0, 0 »로 설정한다. -
options.
strides가 exist하지 않으면, options.strides를 list « 1, 1 »로 설정한다. -
options.
outputSizes가 존재하면: -
options.
dilations가 exist하지 않으면, options.dilations를 list « 1, 1 »로 설정한다. -
desc를 input.
[[descriptor]]의 copy로 둔다. -
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 중 하나라도 유효한 dimension이 아니면,
TypeError를 throw한다. -
options.
layout에 대해 switch한다: -
desc.
shape를 outputShape로 설정한다.
-
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 op 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| N |
slope
| 같음 input
| N |
| output | 같음 input
| N |
MLPreluSupportLimits는
다음 멤버를 가진다:
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. slope, 타입은 MLTensorLimits-
slope 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
prelu()에
대해 다음 멤버를 가진다:
prelu, 타입은 MLPreluSupportLimits-
prelu()오퍼레이터에 대한 지원 제한.
prelu(input, slope, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input 및 slope 중 어느 하나가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input 또는 slope 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
outputShape를 slope의 shape와 input의 shape를 bidirectionally broadcasting한 결과로 둔다.
-
descriptor를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 slope 및 options가 주어진 "prelu" 연산에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| operation steps의 일부로 지정됨 | N |
| output | 같음 input
| N |
MLOpSupportLimits는
reduction operations에 대해 다음 멤버를 가진다:
reduceL1, 타입은 MLSingleInputSupportLimits-
reduceL1()오퍼레이터에 대한 지원 제한. reduceL2, 타입은 MLSingleInputSupportLimits-
reduceL2()오퍼레이터에 대한 지원 제한. reduceLogSum, 타입은 MLSingleInputSupportLimits-
reduceLogSum()오퍼레이터에 대한 지원 제한. reduceLogSumExp, 타입은 MLSingleInputSupportLimits-
reduceLogSumExp()오퍼레이터에 대한 지원 제한. reduceMax, 타입은 MLSingleInputSupportLimits-
reduceMax()오퍼레이터에 대한 지원 제한. reduceMean, 타입은 MLSingleInputSupportLimits-
reduceMean()오퍼레이터에 대한 지원 제한. reduceMin, 타입은 MLSingleInputSupportLimits-
reduceMin()오퍼레이터에 대한 지원 제한. reduceProduct, 타입은 MLSingleInputSupportLimits-
reduceProduct()오퍼레이터에 대한 지원 제한. reduceSum, 타입은 MLSingleInputSupportLimits-
reduceSum()오퍼레이터에 대한 지원 제한. reduceSumSquare, 타입은 MLSingleInputSupportLimits-
reduceSumSquare()오퍼레이터에 대한 지원 제한.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16",
"int64",
"int32",
"int8"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
relu()에
대해 다음 멤버를 가진다:
relu, 타입은 MLSingleInputSupportLimits-
relu()오퍼레이터에 대한 지원 제한.
relu(input, options) 메서드
단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 options가 주어진 "relu" 연산에 대한 오퍼레이터로 둔다.
-
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]이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16",
"uint8",
"int8"
| 4 |
| output | 같음 input
| 4 |
MLOpSupportLimits는
resample2d()에
대해 다음 멤버를 가진다:
resample2d, 타입은 MLSingleInputSupportLimits-
resample2d()오퍼레이터에 대한 지원 제한.
resample2d(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 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까지의 range 안에 있지 않으면, exclusive,TypeError를 throw한다. -
output shape 계산하기:
-
inputDescriptor를 input.
[[descriptor]]로 둔다. -
0부터 options.
axes의 size까지의 range에 있는 각 index에 대해 For each, exclusive: -
desc를 inputDescriptor.
dataType및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
-
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 "resample2d" 연산에 대한 오퍼레이터로 둔다.
-
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로
지정된다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| N |
MLOpSupportLimits는
reshape()에
대해 다음 멤버를 가진다:
reshape, 타입은 MLSingleInputSupportLimits-
reshape()오퍼레이터에 대한 지원 제한.
reshape(input, newShape, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
newShape의 size가 (이 표에 따른) output tensor의 허용되는 ranks가 아니면,
TypeError를 throw한다. -
outputShape를
unsigned long의 빈 array로 둔다. -
newShape의 어떤 item이라도 유효한 dimension이 아니면,
TypeError를 throw한다. -
inputElementCount를 input의 shape에 있는 모든 items의 곱으로 둔다. 빈 dimensions는 inputElementCount 1을 산출한다.
-
newShape의 모든 값의 곱이 inputElementCount와 같지 않으면,
TypeError를 throw한다. -
desc를 input.
[[descriptor]]의 copy로 둔다. -
desc.
shape를 newShape로 설정한다. -
그래프 연결 만들기:
-
output을 this와 desc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 options가 주어진 "reshape" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
reverse()에
대해 다음 멤버를 가진다:
reverse, 타입은 MLSingleInputSupportLimits-
reverse()오퍼레이터에 대한 지원 제한.
reverse(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
inputRank를 input의 rank로 둔다.
-
axes가 주어지지 않았으면, axes를 0부터 inputRank까지의 range로 둔다, exclusive.
-
그렇지 않고, axes가 중복 값을 포함하거나, 그것의 elements 중 하나라도 0부터 inputRank까지의 range 안에 있지 않으면, exclusive, failure를 반환한다.
-
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 "reverse" 연산 및 options에 대한 오퍼레이터로 둔다.
-
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"타입이어야 하며, -N(inclusive)부터 N(exclusive)까지의 범위 안에 있어야 한다. 여기서 N은 options.axis로 index되는 input dimension의 size이고, negative index는 dimension의 끝에서부터 indexing함을 의미한다. -
updates:MLOperand. input 위에 대체할 새 값들로, indices와 같은 shape를 가진다. -
options: 선택적MLScatterOptions. 연산의 선택적 매개변수.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1부터 N까지 |
indices
| "int32",
"uint32",
"int64"
| 같음 input
|
updates
| 같음 input
| 같음 input
|
| output | 같음 input
| 같음 input
|
MLScatterSupportLimits는
다음 멤버를 가진다:
input, 타입은 MLTensorLimits-
input 피연산자에 대한
MLTensorLimits. indices, 타입은 MLTensorLimits-
indices 피연산자에 대한
MLTensorLimits. updates, 타입은 MLTensorLimits-
updates 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
scatterElements()에
대해 다음 멤버를 가진다:
scatterElements, 타입은 MLScatterSupportLimits-
scatterElements()오퍼레이터에 대한 지원 제한.
indices
parameter를 scatterElements()에
대해 graph가 build될 때 허용 범위로 clamp할 수 없다. inputs는 실행 시점까지 알 수 없기 때문이다.
지정된 clamping behavior가 기반 플랫폼에서 제공되지 않는 경우, 구현은 compiled graph에 clamp()를
도입할 수 있다. 마찬가지로, 기반 플랫폼이 negative indices를 지원하지 않는 경우, 구현은 dimension의 끝에서부터의
negative index를 positive index로 변환하기 위해 compiled graph에 operations를 도입할 수 있다.
scatterElements(input, indices, updates, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, indices 및 updates 중 어느 하나가 주어졌을 때 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의 copy로 둔다.
-
indicesShapeExpected[axis]를 indices의 shape[axis]로 설정한다.
-
indices의 shape가 indicesShapeExpected와 같지 않으면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 input, indices, updates 및 options가 주어진 "scatterElements" 연산에 대한 오퍼레이터로 둔다.
-
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 array는 output tensor 전체 좌표를 포함하며, 가장 오른쪽 dimension은 coordinate당 dimension 수를 담는다. 따라서 shape [10,1]인 indices tensor는 10개의 단일-axis indices를 담고, shape [4,3]은 3D coordinates의 indices 4개를 담는다. 값은"int32","uint32", 또는"int64"타입이어야 하며, 각각은 -N(inclusive)부터 N(exclusive)까지의 범위 안에 있어야 한다. 여기서 N은 해당 output dimension의 size이고, negative index는 해당 dimension의 끝에서부터 indexing함을 의미한다. -
updates:MLOperand. input 위에 대체할 새 값들. -
options: 선택적MLScatterOptions. 연산의 선택적 매개변수.
반환: MLOperand.
input의
rank + indices의
rank - indices의
shape[-1] - 1과 같은
rank를 가지는 output N-D
tensor.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1부터 N까지 |
indices
| "int32",
"uint32",
"int64"
| 1부터 N까지 |
updates
| 같음 input
| N |
| output | 같음 input
| 1부터 N까지 |
MLOpSupportLimits는
scatterND()에
대해 다음 멤버를 가진다:
scatterND, 타입은 MLScatterSupportLimits-
scatterND()오퍼레이터에 대한 지원 제한.
indices
parameter를 scatterND()에
대해 graph가 build될 때 허용 범위로 clamp할 수 없다. inputs는 실행 시점까지 알 수 없기 때문이다.
지정된 clamping behavior가 기반 플랫폼에서 제공되지 않는 경우, 구현은 compiled graph에 clamp()를
도입할 수 있다. 마찬가지로, 기반 플랫폼이 negative indices를 지원하지 않는 경우, 구현은 dimension의 끝에서부터의
negative index를 positive index로 변환하기 위해 compiled graph에 operations를 도입할 수 있다.
scatterND(input, indices, updates, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input, indices 및 updates 중 어느 하나가 주어졌을 때 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로 둔다.
-
0부터 indexableSize까지의 range에 있는 각 index에 대해 For each, exclusive:
-
indicesShape[index]를 expectedUpdatesShape에 append한다.
-
-
coordinateSize부터 inputRank까지의 range에 있는 각 index에 대해 For each, exclusive:
-
inputShape[index]를 expectedUpdatesShape에 append한다.
-
-
updates의 shape가 expectedUpdatesShape와 같지 않으면,
TypeError를 throw한다. -
outputShape를 input의 shape의 copy로 둔다.
-
outputDesc를 input의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 outputDesc가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 input, indices, updates 및 options가 주어진 "scatterND" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
sigmoid()에
대해 다음 멤버를 가진다:
sigmoid, 타입은 MLSingleInputSupportLimits-
sigmoid()오퍼레이터에 대한 지원 제한.
sigmoid(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 options가 주어진 "sigmoid" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| 같음 input
|
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| 1부터 N까지 |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
softmax()에
대해 다음 멤버를 가진다:
softmax, 타입은 MLSingleInputSupportLimits-
softmax()오퍼레이터에 대한 지원 제한.
softmax(input, axis, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 axis 및 options가 주어진 "softmax" 연산에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
softplus()에
대해 다음 멤버를 가진다:
softplus, 타입은 MLSingleInputSupportLimits-
softplus()오퍼레이터에 대한 지원 제한.
softplus(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 copy한 결과로 둔다.
-
operator를 "softplus" 연산 및 options에 대한 오퍼레이터로 둔다.
-
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
softsign()에
대해 다음 멤버를 가진다:
softsign, 타입은 MLSingleInputSupportLimits-
softsign()오퍼레이터에 대한 지원 제한.
softsign(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 "softsign" 연산 및 options에 대한 오퍼레이터로 둔다.
-
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이다.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 1부터 N까지 |
| outputs | 같음 input
| 같음 input
|
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. 연산의 선택적 매개변수를 지정한다.
반환:
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| "float32",
"float16"
| N |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
tanh()에
대해 다음 멤버를 가진다:
tanh, 타입은 MLSingleInputSupportLimits-
tanh()오퍼레이터에 대한 지원 제한.
tanh(input, options) 메서드
단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "tanh" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| 같음 input
|
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | N |
| output | 같음 input
| 같음 input
|
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
input
| any | 2부터 N까지 |
| output | 같음 input
| 같음 input
|
MLOpSupportLimits는
triangular()에
대해 다음 멤버를 가진다:
triangular, 타입은 MLSingleInputSupportLimits-
triangular()오퍼레이터에 대한 지원 제한.
triangular(input, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 input이 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
input의 rank가 (이 표에 따른) 그 허용되는 rank 중 하나가 아니면,
TypeError를 throw한다. -
그래프 연결 만들기:
-
output을 input이 주어졌을 때 MLOperand를 복사한 결과로 둔다.
-
operator를 options가 주어진 "triangular" 연산에 대한 오퍼레이터로 둔다.
-
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.
| 피연산자 | 허용되는 데이터 타입 | 허용되는 rank |
|---|---|---|
condition
| "uint8"
| N |
trueValue
| any | N |
falseValue
| 같음 trueValue
| N |
| output | 같음 trueValue
| N |
MLWhereSupportLimits는
다음 멤버를 가진다:
condition, 타입은 MLTensorLimits-
condition 피연산자에 대한
MLTensorLimits. trueValue, 타입은 MLTensorLimits-
trueValue 피연산자에 대한
MLTensorLimits. falseValue, 타입은 MLTensorLimits-
falseValue 피연산자에 대한
MLTensorLimits. output, 타입은 MLTensorLimits-
output 피연산자에 대한
MLTensorLimits.
MLOpSupportLimits는
where()에
대해 다음 멤버를 가진다:
where, 타입은 MLWhereSupportLimits-
where()오퍼레이터에 대한 지원 제한.
where(condition, trueValue, falseValue, options)
메서드 단계는 다음과 같다:
-
this가 빌드할 수 없으면, "
InvalidStateError"DOMException을 throw한다. -
피연산자를 검증한 결과가 this와 condition, trueValue 및 falseValue 중 어느 하나가 주어졌을 때 false를 반환하면,
TypeError를 throw한다. -
condition, trueValue 또는 falseValue 중 어느 하나의 dataType이 (이 표에 따른) 그 허용되는 데이터 타입 중 하나가 아니면,
TypeError를 throw한다. -
outputShape를 trueValue의 shape와 falseValue의 shape를 bidirectionally broadcasting한 결과로 둔다.
-
outputShape를 condition의 shape와 outputShape를 bidirectionally broadcasting한 결과로 설정한다.
-
descriptor를 trueValue의 dataType 및 outputShape가 주어졌을 때 MLOperandDescriptor를 생성한 결과로 둔다.
-
그래프 연결 만들기:
-
output을 this와 descriptor가 주어졌을 때 MLOperand를 생성한 결과로 둔다.
-
operator를 condition, trueValue, falseValue 및 options가 주어진 "where" 연산에 대한 오퍼레이터로 둔다.
-
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)