PALM позволяет кастомизировать следующие компоненты:
При добавлении нового типа компонента требуется реализовать методы, описанные в интерфейсном классе, расположенном в директории данного типа компонента. Если желаемый новый компонент имеет аналогичную функциональность встроенному компоненту, то при его реализации можно использовать наследование от существующего встроенного компонента и менять только необходимые методы.
Интерфейсный класс для head находится в paddlepalm/head/base_head.py
.
Этот интерфейсный класс определяется следующим образом:
# -*- coding: UTF-8 -*-
# Copyright (c) 2019 PaddlePalm Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import json
import copy
``````python
class Head(object):
def __init__(self, phase='train'):
"""Эта функция создает голову задачи, которая должна включать хотя бы один параметр `phase`.
Обратите внимание: при реализации этого конструктора обязательно вызвать конструктор базового класса,
чтобы создать необходимые члены переменных, встроенные в рамках системы.
Аргументы:
phase: тип str. Используется для различия этапа выполнения задачи, когда она вызывается.
В настоящее время поддерживаются этапы обучения 'train' и прогнозирования 'predict'.
"""
self._stop_gradient = {}
self._phase = phase
self._prog = None
self._results_buffer = []
@property
def inputs_attrs(self):
"""Описание объектов входных данных уровня `step`."""
``` Описывает объекты входных данных, на которых зависит текущий головной модуль (head module), включая reader,
backbone и выходные данные других головных модулей (каждый шаг получения один раз). Используется словарь для
описания, где ключами являются компоненты, содержащие выходные данные (например, 'reader', 'backbone' и т.д.),
а значениями — наборы выходных данных, необходимых для данного головного модуля внутри каждого компонента.
Наборы выходных данных также описываются с помощью словарей, где ключами являются названия выходных данных
(название должно быть уникальным среди всех выходных данных соответствующего компонента), а значениями — форма
(shape) и тип данных (dtype) этих выходных данных. Когда размер одного из измерений может меняться, соответствующее
измерение формы устанавливается как -1.
Возвращает:
Словарь типа dict, который описывает входные данные уровня step, зависящие от текущего головного модуля."""
raise NotImplementedError()
@property
def outputs_attr(self):
"""Описание объектов выходных данных уровня step.""" Описывает выходные данные текущего головного модуля (каждый шаг выводится один раз), включая название каждого
выходного объекта, его форму (shape) и тип данных (dtype). Выходные объекты добавляются в список fetch_list,
что позволяет получать актуальные вычисления в каждом шаге обучения/вывода. Эти вычисления могут передаваться
методу batch_postprocess для выполнения последующей обработки текущего шага. Когда объект имеет скалярный тип
данных (например, str, int, float и т.д.), форма устанавливается как пустой список []. Когда размер одного из
измерений может меняться, соответствующее измерение формы устанавливается как -1.```markdown
@property
def epoch_inputs_attrs(self):
"""Описание входных объектов задач уровня epoch.
Описывает выходные объекты, зависящие от выводов reader, backbone и других голов задач (генерируются один раз после каждого epoch), такие как полное множество образцов, количество эффективных образцов и т.д. Описание выполняется с помощью словаря, где ключами являются компоненты, содержащие выходные объекты (например, 'reader', 'backbone' и т.д.), а значениями — наборы выходных объектов, требуемых конкретной головой задачи в этой компоненте. Набор выходных объектов также описывается словарём, где ключами являются названия выходных объектов (название должно быть уникальным среди всех выходных объектов данной компоненты), а значениями — форма (shape) и тип данных (dtype) этих объектов. Когда размер одного из измерений объекта может меняться, соответствующее измерение формы устанавливается равным -1."""
return {
'reader': {'samples': {'shape': (-1,), 'dtype': 'int32'}},
'backbone': {'effective_samples_count': {'shape': (), 'dtype': 'int32'}}
}
``````markdown
## Возвращает:
Словарь типа `dict`, который описывает выходные объекты, создаваемые данной головой задачи. Обратите внимание, что во время обучения обязательно должен присутствовать выходной объект с названием `loss`.
```python
def build(self, inputs, scope_name=""):
"""Создание вычислительной схемы для задачи."""
return {}
``` Преобразование статических графиков Variables, соответствующих описанию inputs_attrs, в статические графики Variable, соответствующие описанию outputs_attr.
Аргументы:
inputs: словарь типа dict. Включает отображение имен объектов из различных наборов объектов на вычислительные графики Variables, входящие в inputs, должны содержать хотя бы те объекты, которые определены в inputs_attr.
Возвращаемое значение:
Вычислительные графики Variables, которые требуется вернуть. Эти выходные объекты будут добавлены в fetch_list, чтобы получить результаты выполнения во время каждого шага обучения/вывода, который будет передан методу postprocess для дальнейшей обработки пользователями.
"""
raise NotImplementedError()
def batch_postprocess(self, rt_outputs):
"""Пакетная/шаговая обработка после выполнения.
Обработка актуальных результатов выполнения текущего пакета после каждого шага обучения/вывода.
По умолчанию результаты выводятся в буфер self._results_buffer."""
if isinstance(rt_outputs, dict):
keys = rt_outputs.keys()
vals = [rt_outputs[k] for k in keys]
lens = [len(v) for v in vals]
if len(set(lens)) == 1:
results = [dict(zip(*[keys, i])) for i in zip(*vals)]
self._results_buffer.extend(results)
return results
else:
print('ПРЕДУПРЕЖДЕНИЕ: Нерегулярные результаты выполнения. Визуализация невозможна.')
self._results_buffer.append(rt_outputs)
return None```markdown
## Очистка буфера задачи
Метод `reset()` очистка буфера задачи (накопленных результатов обработки во время обучения или вывода).
```python
def reset(self):
"""Очистка буфера задачи (накопленных результатов обработки во время обучения или вывода)."""
self._results_buffer = []
Метод get_results()
возвращает накопленные результаты обработки текущей задачи.
def get_results(self):
"""Возвращает накопленные результаты обработки текущей задачи."""
return copy.deepcopy(self._results_buffer)
Метод epoch_postprocess(post_inputs=None, output_dir=None)
выполняет обработку после завершения каждой эпохи обучения или вывода. После завершения каждой эпохи обучения или вывода выполняется обработка накопленных результатов обработки samples. По умолчанию, когда output_dir
равно None
, результаты выводятся на экран. Когда указано место хранения output_dir
, результаты сохраняются в указанной директории, используя название этапа задачи как имя файла.
Аргументы:
post_inputs
: Когда объявленный epoch_inputs_attr
не пустой, этот аргумент будет содержать соответствующие входные данные.output_dir
: Путь для сохранения накопленных результатов.def epoch_postprocess(self, post_inputs=None, output_dir=None):
"""Эпоха уровня обработка после выполнения.
После завершения каждой эпохи обучения или вывода выполняется обработка накопленных результатов обработки samples. По умолчанию, когда output_dir равно None, результаты выводятся на экран. Когда указано место хранения output_dir, результаты сохраняются в указанной директории, используя название этапа задачи как имя файла."""
if output_dir is not None:
for i in self._results_buffer:
print(i)
else:
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(os.path.join(output_dir, self._phase), 'w') as writer:
for i in self._results_buffer:
writer.write(json.dumps(i) + '\n')
При создании нового Head на основе базового класса необходимо реализовать следующие методы:
__init__()
inputs_attrs()
outputs_attr()
build()
- epoch_inputs_attrs
- batch_postprocess
- epoch_postprocess
### Самостоятельное определение backbone
Интерфейсный класс для backbone расположен в `paddlepalm/backbone/base_backbone.py`.
Он определяется следующим образом:
```python
# -*- coding: UTF-8 -*-
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class Backbone(object):
"""Интерфейс модели backbone."""
def __init__(self, phase):
"""Этот метод выполняет конструирование основной сети, которое должно включать хотя бы один параметр phase.
Внимание: При реализации этого конструктора, обязательно вызвать конструктор базового класса для создания необходимых внутренних членов.
Аргументы:
phase: str тип. Используется для разделения этапа выполнения основной сети, поддерживаются этапы тренировки train и предсказания predict."""
``` assert isinstance(phase, str)
@property
def inputs_attr(self):
"""Описание атрибутов входных объектов, требуемых backbone от reader, включая названия, формы и типы данных каждого объекта. Когда объект является скалярным типом данных (например, str, int, float и т.д.), форма устанавливается как пустой список []. Если длина одного из измерений объекта может меняться, соответствующее измерение формы устанавливается как -1."""
Возвращает:
словарь типа. Описание атрибутов каждого входного объекта. Например,
для задач классификации и сопоставления текстов bert backbone зависит от следующих объектов reader:
{"token_ids": ([-1, max_len], 'int64'),
"input_ids": ([-1, max_len], 'int64'),
"segment_ids": ([-1, max_len], 'int64'),
"input_mask": ([-1, max_len], 'float32')}"""
raise NotImplementedError()
@property
def outputs_attr(self):
"""Описание атрибутов выходных объектов, включая названия, формы и типы данных каждого объекта. Когда объект является скалярным типом данных (например, str, int, float и т.д.), форма устанавливается как пустой список []. Когда длина одного из измерений объекта может меняться, соответствующее измерение формы устанавливается как -1.
Возвращает:
словарь типа. Описание атрибутов каждого выходного объекта. Например,
для задач классификации и сопоставления текстов выходные данные bert backbone могут включать следующие объекты:
{"word_emb": ([-1, max_seqlen, word_emb_size], 'float32'),
"sentence_emb": ([-1, hidden_size], 'float32'),
"sim_vec": ([-1, hidden_size], 'float32')}"""
raise NotImplementedError()
``` def build(self, inputs):
"""Создает вычислительную графику backbone. Преобразует статическую графику Variable, соответствующую inputs_attr, в статическую графику Variable, соответствующую outputs_attr.
Аргументы:
inputs: словарь типа dict. Содержит отображение имен объектов из inputs_attr на соответствующие Variable вычислительной графики. В inputs обязательно должны присутствовать все объекты, определенные в inputs_attr.
Возвращает:
Выходные Variable вычислительной графики, которые будут добавлены в fetch_list, чтобы получать результаты выполнения во время каждого шага обучения/вывода. Эти результаты затем передаются методу postprocess для дальнейшей обработки пользователями."""
raise NotImplementedError()
При создании нового объекта Backbone на основе базового класса необходимо реализовать следующие методы:- `__init__`
- `input_attrs`
- `output_attr`
- `build`
### Пользовательское определение reader
Интерфейсный класс (`Interface`) для reader расположен в файле `paddlepalm/reader/base_reader.py`.
Этот интерфейсный класс определяется следующим образом:
```python
# -*- coding: UTF-8 -*-
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from copy import copy
class Reader(object):
"""Интерфейс для читателя данных."""
def __init__(self, phase='train'):
"""Метод инициализирует новый экземпляр читателя данных. Он должен принимать хотя бы один параметр phase.
Внимание: при реализации этого конструктора обязательно вызвать конструктор базового класса для создания необходимых внутренних переменных.
Аргументы:
phase: str тип. Определяет этап выполнения основной сети, поддерживаются тренировочный этап train и этап прогнозирования predict
"""
self._phase = phase
self._batch_size = None
self._num_epochs = 1
self._register = set()
self._registered_backbone = None
@classmethod
def create_register(cls):
return set()
def clone(self, phase='train'):
"""Создает клон текущего экземпляра читателя."""
if phase == self._phase:
return copy(self)
else:
ret = copy(self)
ret._phase = phase
return ret
``` def require_attr(self, attr_name):
"""Добавляет новый атрибут в регистратор."""
Аргументы:
attr_name: имя объекта, который требуется вывести, например 'segment_ids'.
self._register.add(attr_name)
def register_with(self, backbone):
"""Регистрирует каждый зависимый входной объект в регистре в зависимости от backbones."""
Аргументы:
backbone: необходимый для подключения основной сетевой структура.
for attr in backbone.inputs_attr:
self.require_attr(attr)
self._registered_backbone = backbone
def get_registered_backbone(self):
"""Возвращает основную сеть, зарегистрированную этим читателем."""
return self._registered_backbone
def _get_registed_attrs(self, attrs):
ret = {}
for i in self._register:
if i not in attrs:
raise NotImplementedError('выходной атрибут {} не найден в этом читателе.'.format(i))
ret[i] = attrs[i]
return ret
def load_data(self, input_file, batch_size, num_epochs=None,
file_format='tsv', shuffle_train=True):
"""Загружает данные с диска в читатель.
Примечание: при реализации этого метода необходимо создать self._batch_size и self._num_epochs одновременно.
""" Аргументы:
input_file: путь к файлу данных. Формат файла должен удовлетворять параметру `file_format`.
batch_size: количество образцов, выдаваемых итератором за один вызов. Обратите внимание: если в среде присутствуют несколько GPU, значение batch_size должно делиться на количество карт без остатка.
num_epochs: количество проходов по всем данным. По умолчанию None, что означает один проход в режиме одного задания и автоматическое назначение значения сверху в режиме нескольких заданий. Этот параметр действует только во время обучения.
file_format: формат входного файла. Поддерживаемые форматы: tsv. По умолчанию tsv.
shuffle_train: перемешивать ли выборку для обучения. По умолчанию True. Этот параметр действует только во время обучения.
"""
raise NotImplementedError()
```markdown
@property
def outputs_attr(self):
"""Описание атрибутов объекта вывода читателя (объекта, который был выдан с помощью yield), включая имя каждого объекта,
его форму и тип данных. Когда объект является скалярным типом данных (например, str, int, float),
форма устанавливается как пустой список []. Когда размер одного из измерений объекта может меняться,
соответствующее измерение формы устанавливается как -1. Обратите внимание: при использовании стратегии обучения
mini-batch градиентного спуска, должна быть установлена размерность batch_size для обычных входных объектов (обычно -1)."""
``` Возвращает:
Словарь. Описание атрибутов каждого входного объекта. Например,
для задач классификации и совпадения текста, выходные данные могут содержать следующие объекты (downstream backbone и task могут иметь доступ к этим объектам по мере необходимости):
{"token_ids": ([-1, max_len], 'int64'),
"input_ids": ([-1, max_len], 'int64'),
"segment_ids": ([-1, max_len], 'int64'),
"input_mask": ([-1, max_len], 'float32'),
"label": ([-1], 'int')}
"""
raise NotImplementedError() def _iterator(self):
"""Интерфейс для прохода по набору данных. Обратите внимание, что когда набор данных достигает конца,
этот интерфейс должен автоматически выполнить сброс указателя, то есть начать новый проход с начала набора данных.
Возвращает:
Словарь. Выходной объект текущего шага, соответствующий описанию outputs_attr.
"""
raise NotImplementedError()
def get_epoch_outputs(self):
"""Возвращает объекты выходных данных после прохождения каждого эпохи в наборе данных."""
raise NotImplementedError()
@property
def num_examples(self):
"""Количество примеров в наборе данных, то есть количество образцов, сгенерированных iterator'ом в каждой эпохе. Обратите внимание, что при использовании стратегий, таких как скользящее окно, вызывающих изменения количиства образцов в наборе данных, этот интерфейс должен вернуть фактическое количество образцов во время выполнения."""
raise NotImplementedError()
@property
def num_epochs(self):
"""Количество проходов по набору данных"""
return self._num_epochs
В основе родительского класса, при определении нового читателя (reader) необходимо реализовать следующие методы:
- \_\_init\_\_
- outputs_attr
- load_data
- _iterator
- num_examples
Методы, которые можно переопределить:
- get_epoch_outputs
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )