Какова роль смещения в нейронных сетях?


807

Я знаю о градиентном спуске и алгоритме обратного распространения. Чего я не понимаю, так это когда важно использовать предвзятость и как вы ее используете?

Например, при отображении ANDфункции, когда я использую 2 входа и 1 выход, она не дает правильных весов, однако, когда я использую 3 входа (1 из которых является смещением), она дает правильные веса.


17
Проверьте этот вопрос: stackoverflow.com/questions/1697243/help-with-perceptron для примера реальной проблемы, когда OP не использовал термин смещения
Amro

6
И вот хороший пример на Python того, почему смещение важно :) stackoverflow.com/questions/38248657/…
минералы

3
Вот отличная статья, полная математики backprop
Энди

Ответы:


1361

Я думаю, что предубеждения почти всегда полезны. По сути, значение смещения позволяет смещать функцию активации влево или вправо , что может иметь решающее значение для успешного обучения.

Это может помочь взглянуть на простой пример. Рассмотрим эту сеть с 1 входом и 1 выходом, которая не имеет смещения:

простая сеть

Выход сети рассчитывается путем умножения входных данных (х) на вес (W 0 ) и передачи результата через некоторую функцию активации (например, сигмовидную функцию).

Вот функция, которую эта сеть вычисляет для различных значений w 0 :

выходной сигнал сети при различных весах w0

Изменение веса w 0 существенно меняет «крутизну» сигмовидной кишки. Это полезно, но что если вы хотите, чтобы сеть выводила 0, когда х равен 2? Простое изменение крутизны сигмоида не сработает - вы хотите иметь возможность сместить всю кривую вправо .

Это именно то, что позволяет сделать уклон. Если мы добавим смещение в эту сеть, вот так:

простая сеть с уклоном

... тогда выходной сигнал сети становится sig (w 0 * x + w 1 * 1.0). Вот как выглядит выход сети для различных значений w 1 :

выходная сеть с учетом различных весовых коэффициентов w1

При весе -5 для w 1 кривая сдвигается вправо, что позволяет нам иметь сеть, которая выводит 0, когда x равен 2.


6
@ user1621769: Самый простой подход - это сеть с одним узлом смещения, который подключается ко всем не входным узлам в сети.
Нейт Кол

65
@ user1621769: Основная функция смещения - предоставить каждому узлу обучаемое постоянное значение (в дополнение к обычным входам, которые получает узел). Этого можно добиться с помощью одного узла смещения с подключениями к N узлам или с N узлами смещения, каждое из которых имеет одно соединение; результат должен быть таким же.
Нейт Коля

4
@ user1621769: Возможно, вы не учитываете веса? Каждое соединение имеет обучаемое взвешивание, а узел смещения имеет фиксированное значение.
Димпл

4
@ user132458, если алгоритм обучения определит, что вам не требуется сдвиг смещения, весовые коэффициенты смещения, вероятно, приблизятся к 0. Таким образом устраняется сигнал смещения.
Йоргенкг

8
@ Габриэль: должен быть один уклон на скрытый нейрон.

343

Просто чтобы добавить мои два цента.

Более простой способ понять, что такое смещение: оно чем-то похоже на константу b линейной функции

у = топор + б

Это позволяет вам перемещать линию вверх и вниз, чтобы лучше соответствовать прогнозу с данными. Без b линия всегда проходит через начало координат (0, 0), и вы можете получить худшее соответствие.


5
хорошая анология, но если мы установим смещение в 1, то почему это имеет значение для подгонки теперь, когда каждая строка теперь будет проходить через (0,1) вместо (0,0)? Поскольку все линии теперь смещены к y = 1 вместо y = 0, почему это полезно?
голубое небо

36
@ blue-sky Потому что, умножив смещение на вес, вы можете сместить его на произвольную величину.
Carcigenicate

3
Правильно ли называть b «коэффициентом»? Разве «коэффициент» не является числом, используемым для умножения переменной?
Бен

8
б не "коэффициент", скорее это перехват.
Espanta

22
b - коэффициент $ x ^ 0 $. a - коэффициент $ x ^ 1 $

65

Эта тема действительно помогла мне разработать собственный проект. Вот еще несколько иллюстраций, показывающих результат простой двухслойной нейронной сети с прямой связью с блоками смещения и без нее в задаче регрессии с двумя переменными. Веса инициализируются случайным образом и используется стандартная активация ReLU. Как пришли к выводу ответы передо мной, без смещения ReLU-сеть не может отклоняться от нуля при (0,0).

введите описание изображения здесь

введите описание изображения здесь


1
Можете ли вы добавить функцию, которая нанесена с метками оси?
Komal-SkyNET

46

Два разных вида параметров могут быть отрегулированы во время обучения ANN, весов и значений в функциях активации. Это нецелесообразно, и было бы проще, если бы был настроен только один из параметров. Чтобы справиться с этой проблемой, изобретен нейрон смещения. Смещающий нейрон лежит в одном слое, связан со всеми нейронами в следующем слое, но ни с одним на предыдущем слое, и он всегда излучает 1. Поскольку смещающий нейрон излучает 1, веса, связанные с нейроном смещения, добавляются непосредственно к объединенная сумма других весов (уравнение 2.1), как и значение t в функциях активации. 1

Причина, по которой это нецелесообразно, заключается в том, что вы одновременно корректируете вес и значение, поэтому любое изменение веса может нейтрализовать изменение значения, которое было полезно для предыдущего экземпляра данных ... добавление нейрона смещения без изменения значения позволяет вам контролировать поведение слоя.

Кроме того, смещение позволяет использовать одну нейронную сеть для представления похожих случаев. Рассмотрим логическую функцию AND, представленную следующей нейронной сетью:

ЭНН
(источник: aihorizon.com )

  • w0 соответствует b .
  • w1 соответствует x1 .
  • w2 соответствует x2 .

Один персептрон может использоваться для представления множества логических функций.

Например, если мы примем логические значения 1 (истина) и -1 (ложь), то одним из способов использования персептрона с двумя входами для реализации функции AND является установка весов w0 = -3 и w1 = w2 = 0,5. Этот персептрон можно сделать так, чтобы он представлял функцию ИЛИ, изменив порог на w0 = -.3. Фактически, AND и OR могут рассматриваться как особые случаи функций m-of-n: то есть функций, в которых по крайней мере m из n входов в персептрон должно быть истинным. Функция OR соответствует m = 1, а функция AND - m = n. Любую функцию m-of-n легко представить с помощью персептрона, установив все входные веса на одно и то же значение (например, 0,5), а затем соответствующим образом установив порог w0.

Персептроны могут представлять все примитивные логические функции AND, OR, NAND (1 AND) и NOR (1 OR). Машинное обучение - Том Митчелл)

Порог - это смещение, а w0 - вес, связанный с нейроном смещения / порога.


8
Думайте об этом как общее правило: добавьте предвзятость! Нейронные сети в некоторой степени «непредсказуемы», поэтому, если вы добавите нейрон смещения, вы с большей вероятностью найдете решения быстрее, чем если бы вы не использовали смещение. Конечно, это не доказано математически, но это то, что я наблюдал в литературе и в общем использовании.
Кирилл

25

Уклон не является NN термин, это общий термин алгебры для рассмотрения.

Y = M*X + C (уравнение прямой)

Теперь, если C(Bias) = 0тогда, линия всегда будет проходить через начало координат, т.е. (0,0)и зависит только от одного параметра, т.е.M Е. От наклона, поэтому у нас будет меньше вещей для игры.

C, который является смещением, принимает любое число и обладает активностью для смещения графика, и, следовательно, способен представлять более сложные ситуации.

В логистической регрессии ожидаемое значение цели преобразуется функцией связи, чтобы ограничить ее значение единичным интервалом. Таким образом, предсказания модели можно рассматривать как вероятности первичного исхода, как показано ниже: сигмоидальная функция в Википедии

Это последний активационный слой в карте NN, который включает и выключает нейрон. Здесь также играет роль смещение, и оно гибко смещает кривую, чтобы помочь нам отобразить модель.


1
Итак, какие проблемы в обучении / обучении нейронной сети возникают, когда линия всегда проходит через начало координат, когда смещение не используется?
Даниял

@DaniyalJavaid Это может быть возможность, а не проблема
Pradi KL

23

Слой в нейронной сети без смещения - не что иное, как умножение входного вектора на матрицу. (Выходной вектор может быть пропущен через сигмовидную функцию для нормализации и впоследствии для использования в многослойной сети ANN, но это не важно.)

Это означает, что вы используете линейную функцию и, следовательно, вход всех нулей всегда будет отображаться на выход всех нулей. Это может быть разумным решением для некоторых систем, но в целом оно слишком ограничительное.

Используя смещение, вы фактически добавляете другое измерение к своему входному пространству, которое всегда принимает значение, равное единице, поэтому вы избегаете входного вектора всех нулей. Вы не теряете общности из-за этого, потому что ваша обученная матрица веса не должна быть сюръективной, поэтому она все равно может отображать все возможные ранее значения.

2d ANN:

Для ANN, отображающего два измерения в одно измерение, например, при воспроизведении функций AND или OR (или XOR), вы можете думать о нейронной сети как о следующем:

На плоскости 2d отметьте все позиции входных векторов. Итак, для логических значений вы бы хотели отметить (-1, -1), (1,1), (-1,1), (1, -1). Теперь ваша ANN рисует прямую линию на плоскости 2d, отделяя положительный вывод от отрицательных выходных значений.

Без смещения эта прямая линия должна проходить через ноль, в то время как с помощью смещения вы можете положить ее куда угодно. Итак, вы увидите, что без смещения вы столкнулись с проблемой с функцией AND, так как вы не можете поместить и (1, -1), и (-1,1) в отрицательную сторону. (Они не могут быть на линии.) Проблема равна для функции ИЛИ. Однако с уклоном легко провести черту.

Обратите внимание, что функция XOR в этой ситуации не может быть решена даже с предвзятым отношением.


4
Если вы используете сигмоидальную передаточную функцию, вы вводите нелинейность. Утверждать, что это линейная функция, неверно, а также как-то опасно, поскольку нелинейность сигмовидной железы является ключом к решению ряда проблем. Кроме того, сигмоид (0) = 0,5, и нет х, для которого сигмоид (х) = 0.
Байер

2
Да, но это 0,5 для любого входа 0 без смещения, независимо от того, на что похожа линейная функция. И в этом все дело. Обычно вы не тренируете свою сигмовидную функцию, вы просто живете с ней. Проблема линейности возникает задолго до сигмоидальной функции.
Дебильски

Я понял вашу точку зрения: слой не может запоминать другой вывод для 0, чем тот, с которого он начал. Это правильно и важно. Однако «аргумент линейной функции» просто не применим по моему мнению. Даже с уклоном, функция все еще линейна. Свойство линейности вводит в заблуждение здесь. (Да, я мог бы придираться.)
Байер

Я бы сказал, что с уклоном это аффинно . ( en.wikipedia.org/wiki/Affine_transformation#Representation )
Дебилски,

Да вы правы Спасибо за указание на эту разницу для меня. (Почему мы называем это линейной регрессией, между прочим, хотя это аффинно?)
Байер

20

Когда вы используете ANN, вы редко знаете о внутренностях систем, которые вы хотите изучить. Некоторые вещи не могут быть изучены без предвзятости. Например, взгляните на следующие данные: (0, 1), (1, 1), (2, 1), в основном функция, которая отображает любой x на 1.

Если у вас есть одноуровневая сеть (или линейное отображение), вы не сможете найти решение. Однако, если у вас есть предвзятость, это тривиально!

В идеальном случае смещение может также отобразить все точки на среднее значение целевых точек и позволить скрытым нейронам моделировать различия от этой точки.


18

Модификация нейронов ВЕСА сама по себе служит только для манипулирования формой / кривизной вашей передаточной функции, а не ее точкой равновесия / пересечения нуля .

Введение смещения нейронов позволяет смещать кривую передаточной функции по горизонтали (влево / вправо) вдоль входной оси, оставляя форму / кривизну без изменений. Это позволит сети создавать произвольные выходные данные, отличные от значений по умолчанию, и, следовательно, вы можете настроить / сместить отображение ввода-вывода в соответствии с вашими конкретными потребностями.

Смотрите здесь для графического объяснения: http://www.heatonresearch.com/wiki/Bias


16

Просто добавить ко всему этому то, чего очень не хватает, а остальное, скорее всего, не знает.

Если вы работаете с изображениями, вы можете вообще не использовать смещение. Теоретически, таким образом ваша сеть будет более независимой от величины данных, например, будет ли изображение темным или ярким и ярким. И сеть научится выполнять свою работу, изучая относительность внутри ваших данных. Многие современные нейронные сети используют это.

Для других данных наличие смещения может быть критическим. Это зависит от типа данных, с которыми вы имеете дело. Если ваша информация не зависит от величины --- если ввод [1,0,0,1] должен привести к тому же результату, что и ввод [100,0,10], вам может быть лучше без смещения.


тебе наверное лучше с нормализацией. Каков пример современной сети, которая использует «отсутствие смещения» для создания инвариантности величин?
Проснулся, Зная

@Awoke Зная, я полагаю, обычный ResNet использует это, поскольку это является частью его «инициализации», но я не совсем уверен, что они сделали это исключительно для этой цели, или, может быть, из соображений размера / эффективности модели, и я Я не уверен, что эта концепция опубликована где-либо. Но я думаю, что это вполне понятно на уровне теории. Если у вас нет смещения, которое не масштабируется, при масштабировании значений все выходы просто масштабируются соответственно. Осознавая эту концепцию или нет, большая часть современных архитектур не имеет смещений, по крайней мере, в значительной части их структур.
Хор Ме

16

В нескольких экспериментах в моей магистерской работе (например, на странице 59) я обнаружил, что смещение может быть важным для первого (ых) слоя (ов), но особенно в полностью связанных слоях в конце, похоже, оно не играет большой роли.

Это может сильно зависеть от сетевой архитектуры / набора данных.


Это звучит полностью аналогично процессу моделирования систем «вручную» с линейной регрессией. Простейшей моделью будет Y_bar = mean (Y). Затем вы добавляете сложность, добавляя различные термины X, останавливаясь, когда нет значительного прироста информации.
IRTFM

15

Смещение решает, на какой угол вы хотите, чтобы ваш вес вращался.

В 2-мерной диаграмме вес и смещение помогают нам найти границу принятия решений. Скажем, нам нужно построить функцию AND, пара input (p) -output (t) должна быть

{p = [0,0], t = 0}, {p = [1,0], t = 0}, {p = [0,1], t = 0}, {p = [1,1] , t = 1}

введите описание изображения здесь

Теперь нам нужно найти границу решения, граница идеи должна быть:

введите описание изображения здесь

Видеть? W перпендикулярно нашей границе. Таким образом, мы говорим, что W решил направление границы.

Тем не менее, трудно найти правильный W в первый раз. В основном мы выбираем исходное значение W случайным образом. Таким образом, первая граница может быть такой: введите описание изображения здесь

Теперь граница ближе к оси y.

Мы хотим повернуть границу, как?

Изменяя W.

Итак, мы используем функцию правила обучения: W '= W + P: введите описание изображения здесь

W '= W + P эквивалентно W' = W + bP, а b = 1.

Следовательно, изменяя значение b (смещение), вы можете выбрать угол между W 'и W. Это «правило обучения ANN».

Вы также можете прочитать « Проект нейронной сети» Мартина Т. Хагана / Говарда Б. Демута / Марка Х. Била, глава 4 «Правило обучения перцептрона»


1
Полезное объяснение / иллюстрация
javadba

10

В частности, Нейт ответ , zfy в ответ , и Pradi в ответ велики.

Проще говоря, смещения позволяют изучать / хранить все больше и больше вариаций весов ... ( примечание : иногда с некоторым порогом). В любом случае, больше вариаций означает, что смещения добавляют более полное представление входного пространства к изученным / сохраненным весам модели. (Где лучшие веса могут увеличить способность угадывания нейронной сети)

Например, в моделях обучения гипотеза / предположение желательно ограничено y = 0 или y = 1 при некотором входном сигнале, возможно, в некоторой задаче классификации ... т.е. некотором y = 0 для некоторого x = (1,1) и некоторых у = 1 для некоторого х = (0,1). (Условием для гипотезы / результата является пороговое значение, о котором я говорил выше. Обратите внимание, что в моих примерах входы X каждого элемента задаются равными x = двойному или 2-значному вектору вместо однозначных x входных значений Нейта некоторой коллекции X).

Если мы игнорируем смещение, многие входные данные могут быть представлены многими одинаковыми весами (то есть выученными весами). основном встречаются близко к началу координат (0,0). В этом случае модель будет ограничена меньшими количествами хороших весовых коэффициентов, вместо многих других хороших весов он мог бы лучше учиться с предвзятостью (где плохо изученные веса приводят к худшим догадкам или уменьшению способности угадывать нейронной сети)

Таким образом, оптимальным является то, что модель обучается как вблизи источника, так и в максимально возможном количестве мест внутри границы порога / решения. С предвзятостью мы можем предоставить степени свободы, близкие к источнику, но не ограничиваясь непосредственным регионом происхождения.


9

Расширение объяснения @zfy ... Уравнение для одного входа, одного нейрона, одного выхода должно выглядеть так:

y = a * x + b * 1    and out = f(y)

где x - это значение из входного узла, а 1 - это значение смещения; y может быть непосредственно вашим выводом или передаваться в функцию, часто сигмовидную функцию. Также обратите внимание, что смещение может быть любым постоянным, но чтобы упростить все, мы всегда выбираем 1 (и, вероятно, это так часто, что @zfy сделал это, не показывая и не объясняя это).

Ваша сеть пытается выучить коэффициенты a и b для адаптации к вашим данным. Итак, вы можете понять, почему добавление элементаb * 1 позволяет ему лучше соответствовать большему количеству данных: теперь вы можете изменить как наклон, так и перехват.

Если у вас есть более одного ввода, ваше уравнение будет выглядеть так:

y = a0 * x0 + a1 * x1 + ... + aN * 1

Обратите внимание, что уравнение все еще описывает один нейрон, одну выходную сеть; если у вас больше нейронов, вы просто добавляете одно измерение в матрицу коэффициентов, чтобы мультиплексировать входы во все узлы и суммировать вклад каждого узла.

Что вы можете написать в векторизованном формате как

A = [a0, a1, .., aN] , X = [x0, x1, ..., 1]
Y = A . XT

т.е., помещая коэффициенты в один массив и (входы + смещение) в другой, вы получаете желаемое решение в виде точечного произведения двух векторов (вам нужно переставить X, чтобы фигура была правильной, я написал XT как 'X транспонированный')

Таким образом, в конце вы также можете увидеть свое смещение как еще один вход для представления той части вывода, которая фактически не зависит от вашего ввода.


Кажется, я помню из класса Эндрю Нга, что предвзятость не учитывалась в процессе обучения. Не могли бы вы обновить свой ответ, чтобы объяснить, что, учитывая ваше заключение, что это «просто еще один вклад»?
Проснулся, Зная

@Awoke Зная, я не помню этого из класса Эндрю Нга, но это было несколько лет назад. Также смещение может быть включено или выключено в зависимости от того, что вы пытаетесь выучить. Я читал, что при обработке изображений они не используют его для масштабирования. Для меня, если вы используете это, вы используете это также в обучении. Эффект заключается в стабилизации коэффициентов, когда все или часть входных данных являются нулевыми или почти нулевыми. Почему бы вам не использовать смещение во время обучения, а затем использовать его при использовании NN для прогнозирования выходов для новых входов? Как это может быть полезно?
RobMcZag

Нет, это было больше похоже на использование в прямом проходе, но не используйте его при расчете градиента для backprop, или что-то в этом роде.
Проснулся, Зная

@ Awoke Зная, я полагаю, это способ сэкономить память и время. Вы можете решить, что вам не важно изучать коэффициенты для единиц смещения. Это может быть хорошо, если у вас есть по крайней мере один скрытый слой, поскольку смещение обеспечит некоторый вход для этого слоя, и выходной сигнал может быть получен по коэффициентам от первого до второго слоя. Я не уверен, изменится ли скорость сходимости. В моем примере с одним слоем вы вынуждены также изучать коэффициент смещения при его применении к выходу.
RobMcZag

Во многих простых задачах целевые данные были унижены и масштабированы, поэтому смещения не требуется, а вероятность чрезмерного влияния выбросов в переменных с большими диапазонами уменьшается.
IRTFM

9

Помимо упомянутых ответов .. Я хотел бы добавить некоторые другие моменты.

Уклон действует как наш якорь. Для нас это способ создать некую базовую линию, в которой мы не опускаемся ниже этого уровня. В терминах графа представьте, что y = mx + b - это y-пересечение этой функции.

output = input умножает значение веса и добавляет значение смещения, а затем применяет функцию активации.


8

Проще говоря, если у вас есть y = w1 * x, где y - ваш вывод, а w1 - вес, представьте условие, где x = 0, тогда y = w1 * x равно 0. Если вы хотите обновить свой вес, у вас есть чтобы вычислить, насколько изменилось значение delw = target-y, где target - это целевой результат, в этом случае «delw» не изменится, поскольку y вычисляется как 0. Так что, если вы можете добавить какое-то дополнительное значение, это поможет y = w1 * x + w0 * 1 , где смещение = 1, и вес можно отрегулировать, чтобы получить правильное смещение. Рассмотрите пример ниже.

В терминах линии Наклон-перехват это особая форма линейных уравнений.

у = х + Ь

проверьте изображение

образ

здесь b (0,2)

если вы хотите увеличить его до (0,3), как вы будете делать это, изменив значение b, которое будет вашим смещением


7

Для всех книг по ML, которые я изучал, W всегда определяется как индекс связи между двумя нейронами, что означает, что чем выше связь между двумя нейронами, тем сильнее будут передаваться сигналы от запускающего нейрона к целевому нейрону или Y = w * X в результате, чтобы поддерживать биологический характер нейронов, нам нужно сохранить 1> = W> = -1, но в реальной регрессии W в итоге получит | W | > = 1, что противоречит принципам работы нейронов, поэтому я предлагаю W = cos (theta), а 1> = | соз (тета) | и Y = a * X = W * X + b, в то время как a = b + W = b + cos (тета), b является целым числом


7

В нейронных сетях:

  1. Каждый нейрон имеет уклон
  2. Вы можете просмотреть смещение как порог (обычно противоположные значения порога)
  3. Взвешенная сумма от входных слоев + смещение решает активацию нейрона
  4. Смещение увеличивает гибкость модели.

В отсутствие смещения, нейрон не может быть активирован, рассматривая только взвешенную сумму от входного слоя. Если нейрон не активирован, информация от этого нейрона не передается через остальную часть нейронной сети.

Значение предвзятости легко усваивается.

введите описание изображения здесь

Эффективно, смещение = - порог. Вы можете думать о смещении как о том, как легко заставить нейрон вывести 1 - с действительно большим смещением, нейрону очень легко вывести 1, но если смещение очень отрицательное, тогда это сложно.

в итоге: смещение помогает контролировать значение, при котором активируется функция активации.

Следуйте этому видео для более подробной информации

Еще несколько полезных ссылок:

geeksforgeeks

towardsdatascience


1
Хорошая интерпретация. Но мне не ясно, как предвзятость обучаема (или обучаема?). В простом случае, когда потеря = ReLU (омега * х + а), омега веса может быть обучена с помощью правила цепочки, но как можно рассчитать смещение, aкогда уклон aвсегда постоянен?
Либин Вэнь

4

Термин смещение используется для настройки конечной выходной матрицы, как это делает y-перехват. Например, в классическом уравнении y = mx + c, если c = 0, линия всегда будет проходить через 0. Добавление члена смещения обеспечивает большую гибкость и лучшее обобщение для нашей модели нейронной сети.


0

В общем, в машинном обучении у нас есть эта базовая формула. Смещение отклонения. Поскольку в NN у нас есть проблема переоснащения (проблема обобщения модели, когда небольшие изменения в данных приводят к большим изменениям в результате модели), и из-за этого мы имеем большую дисперсию, вводя небольшой уклон мог бы помочь. Рассматривая формулу выше, смещение отклонения отклонения , где смещение возводится в квадрат, следовательно, введение небольшого смещения может привести к значительному снижению дисперсии. Итак, внесите предвзятость, когда у вас есть большая дисперсия и опасность перегрузки.


3
Bias блоки и диагонально-дисперсии Компромисс отдельные понятия. Вопрос о первом.
SigmaX

0

Смещение помогает получить лучшее уравнение

Представьте, что вход и выход похожи на функцию, y = ax + bи вам нужно поместить правильную линию между входом (x) и выходом (y), чтобы минимизировать глобальную ошибку между каждой точкой и линией. Если вы сохраните уравнение, как это y = ax, у вас будет один параметр только для адаптации, даже если вы найдете лучший, aсводящий к минимуму глобальную ошибку, он будет далеко от желаемого значения

Можно сказать, что смещение делает уравнение более гибким для адаптации к лучшим значениям

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.