Самодельная стратегия, описанная в последнем посте может быть выражена функцией оценки руки:

E = Wh

Где E - это матрица 1 x 52, которая представляет оценку руки (или относительные значения карт в вашей руке ... чем выше значение, тем больше вы хотите их сохранить. ), W - это матрица весов 52 x 52, применяемая к руке, а h - это 1 x 52 матрица, представляющая руку. Как мы перешли от матрицы 4 x 13, представляющей руку, описанную в предыдущем посте, к матрице 1 x 52 здесь? Я только что расплющил матрицу 4 x 13. W, таким образом, представляет отношение каждой карты в колоде к каждой другой карте в колоде.

Вы можете заметить, что это отличается от описанной ранее сверточной матрицы, которая просто учитывает 2–3 ячейки карты, смежные по горизонтали и вертикали. Однако матрица 52 x 52 может вычислять ту же функцию, что и сверточная матрица, применяемая к каждой карте в руке.

Итак, как мне перейти от сверточной матрицы 7 x 7 из предыдущего:

К матрице 52 x 52, которая вычисляет ту же функцию? Это не было бы это сложно сделать вручную, но было бы скучно вводить все 2704 значения W. А компьютерщики ленивы. Не лучше ли использовать машинное обучение, чтобы разобраться в этом за меня? Почему бы не использовать миллионы долларов на исследования и разработки, которые Google вложил в TensorFlow, для работы здесь?

Google TensorFlow

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

Моя цель при использовании TensorFlow была очень скромной: вычислить матрицу 52 x 52, которая выполняет ту же функцию, что и моя матрица свертки 7 x 7 в ручном оценщике джин рамми. Итак, TensorFlow нужно было запустить по нескольким направлениям:

  1. Настройте тренировочные данные
  2. Установите ввод, вывод и параметры
  3. Построить модель
  4. Задайте функцию потерь для оптимизации по

Данные тренировки джина рамми

Данные тренировки, которые я использовал, представляли собой пары из 1) руки игрока (матрица 4 x 13) и 2) итоговой оценки руки (также матрицы 4 x 13). В моей системе, созданной вручную, это вычисляется с использованием сверточной матрицы, приведенной выше. Чтобы сгенерировать эти тренировочные данные, я заставил программу джин рамми воспроизводить несколько тысяч игр, и каждый раз, когда она оценивала руку, она сохраняла пару рука / оценка руки. Так, например, допустим, у нас есть рука:

А созданная вручную система генерирует следующую оценку рук:

Таким образом, обучающие данные составили пару тысяч пар, подобных этим двум, за исключением того, что вместо матриц 4 x 13, подобных приведенным выше (которые легче читать), они были сглажены матрицами 1 x 52.

Вход, выход и параметры для TensorFlow

Код, который сообщает TensorFlow, что является входом (рука) и выходом (оценка руки или значение колоды), очень просто указать:

# Model input and output
h = tf.placeholder(tf.float32, [None, 52], name="hand")       # h = hand
d = tf.placeholder(tf.float32, [None, 52], name="deck_value") # d = deck value

И здесь параметром является W, матрица 52 x 52, которая имеет случайные значения:

# Model parameter
W = tf.Variable(tf.random_normal([52, 52], stddev=0.35), name="weights")

Модель

Модель, которую я выбрал для этого небольшого упражнения, представляет собой простую линейную модель E = Wh. Удобство TensorFlow заключается в возможности использовать декларативные средства для настройки нейронной сети, вместо того, чтобы программировать их функционально.

# Model
linear_model = tf.matmul(h, W)   

Потери и оптимизатор

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

# Loss
loss = tf.reduce_sum(tf.square(linear_model - d)) 
# Optimizer
optimizer = tf.train.GradientDescentOptimizer(0.0001)  
train = optimizer.minimize(loss)      

Матрица результатов обучения

Так как же выглядит W, получившаяся матрица 52 x 52? Здесь показана матрица с цветовой шкалой, темнее зеленый - большее число:

Рад, что мне не пришлось все это вводить.

Следующая остановка: более интересное машинное обучение

Использование TensorFlow очень просто, и это хороший пример того, как его использовать. Однако это не решало интересную проблему само по себе, это было просто удобством для меня как программиста. Что было бы интереснее, так это обнаружить алгоритм, который лучше играет в Gin Rummy, чем моя ручная версия. Этот новый алгоритм будет учитывать больше игровой информации. А как его узнать? Ему пришлось бы сыграть много-много игр против самого себя ...