...

суббота, 8 апреля 2017 г.

Проблема использования CompletableFuture в нескольких потоках и её решение

НДС и фрилансеры работающие с Upwork

[Из песочницы] Проверяем честность игры в рулетку на смарт-контракте Ethereum

Фильтрация изображения методом математической морфологии на FPGA


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

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

  • требует формирование оконной функции
  • очень сложен для расширения окна
  • большое запаздывание (latency) при последовательном соединении с другими оконными функциями.

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

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

Как мы уже выяснили из статьи выше по тексту, из базовых морфологических операций сужение (erosion) и расширение (dilation) можно построить операции открытие (opening) и закрытие (closing).

Операция открытие — это последовательное выполнение erosion -> dilation. Такая комбинация приведёт к тому, что одиночные пиксели и малые их скопления будут безвозвратно сожраны сужением, как и крупные объекты подвергнутся обгладыванию ) по бокам. Если внутри больших объектов были маленькие дырки, то и они станут больше. Последующая операция расширения восстановит обглоданные объекты до первоначальных размеров, однако мелкого мусора, сожранного сужением уже не будет.

Операция закрытие — это последовательное выполнение dilation -> erosion. Эта операция сначала заполнит дырки внутри объектов и сделает их чуть толще, а затем уменьшит их толщину до первоначальной, но дырок больше не будет.

Последовательное выполнение операций opening -> closing является очень хорошим фильтром, ничем не хуже медианного, а напротив, она ещё и объекты сделает нам менее дырявыми. Обязательным условием является одинаковый размер окна для базовых операций.

Однако, каждая базовая операция erosion или dilation являет собой всё ту же оконную функцию, требующую как минимум 2 FIFO для реализации окна 3x3 и логические операции AND или OR в зависимости от функции.

Для более глубокой фильтрации нередко применяют окно 5x5 и 7x7, что влечёт за собой увеличение объёма памяти на элементы FIFO и общее время запаздывания.
Для реализации подобных операций на ПЛИС фирмы Альтера можно использовать мегафункцию FIFO и встроенную 2-х портовую память, однако на одно такое FIFO шириной всего в 1 бит, а большего нам и не надо для бинаризованного изображения, уйдёт целый блок памяти, например M4K, что тоже не очень экономично.

Low complexity метод


Занимаясь поиском альтернативных решений, я наткнулся в сети на, так называемый, low complexity метод. Суть этого метода — декомпозиция матрицы оконной функции.
Исходная матрица раскладывается на две:


и работает согласно этому изображению:

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

В вышеупомянутой статье была представлена функциональная схема реализации операций erosion и dilation с применением low complexity метода. Данная схема состоит из двух блоков, каждый из которых олицетворяет структурный элемент SE1 и SE2.

Из данной схемы понятно, что выбор операций erosion/dilation выполняется инверсией входных данных т.к. эти операции симметричны.

Выход блока Stage-1 зависит от значения входного пикселя и накопленной суммы в триггере ff. Как только эта сумма станет равна ширине окна структурного элемента SE1, на выход блока пойдёт “1” иначе “0”. Любой “0” на входе блока сбрасывает накопленную сумму в триггере ff в ноль. Очевидно, что данный блок подсчитывает количество последовательно идущих единиц под структурным элементом SE1.

Выход блока Stage-1 поступает на вход блока Stage-2, который работает по такому-же принципу. Отличием его от блока Stage-1 является использование памяти Row_mem глубиной в количество столбцов входного изображения, и сумма хранится отдельно для каждого столбца в этой памяти. Выход блока “1” только тогда, когда сумма по столбцу равна высоте структурного элемента SE2. Выходной сигнал блока Stage-2 может быть проинвертирован в зависимости от выполняемой операции erosion или dilation.

Таким образом, получается что в блоке Stage-1 схема отслеживает все “1” под горизонтальным элементом SE1 и результат передаёт в блок Stage-2, который в свою очередь, отслеживает все “1” под вертикальным элементом SE2 учитывая результат выхода SE1.

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

Границы изображения условно обозначены названиями сторон света: North, South, West и East. При нахождении структурного элемента SE на границах изображения, предусмотрена вставка (padding) необходимого количества единиц или нулей, соответствующего половинному размеру структурного элемента.

Большим преимуществом этого метода является экономия памяти. Объем требуемой памяти для блоков Stage-1 и Stage-2 определяется размером слова (WL) равным
Log2(SE1_width) и Log2(SE2_height). Для блока Stage-2 используется не триггер, а память Row_mem, объём которой равен Image_width x Log2(SE2_height).
Очевидно, что результат вычисления логарифма надо округлить до ближайшего значения разрядности SE1_width и SE2_height, т.е. если окно 3x5, то округлённое значение Log2(SE1_width) = 2 бита, а Log2(SE2_height) = 3 бита.

Не сложно заметить, что разницы нет в использовании памяти для окна 3x3 в low complexity методе и обычном оконном. Что в первом случае объём памяти равен 320 столбцов x 2 бита, что во вторм: два однобитных элемента FIFO размером по 320 элементов. Если же размер окна меняется на 5x5 или 7x7, то количество FIFO растёт пропорционально количеству рядов окна, а вот для low complexity метода размер слова увеличится всего лишь на 1 бит, и память Row_mem станет не 320x2, а 320x3.

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

Код модуля erosion/dilation на языке Verilog:

Low complexity erosion/dilation
module low_complexity
    #(parameter BW = 3'd3,
      parameter BH = 3'd3,
      parameter WIDTH = 9'd320,
      parameter HEIGH = 9'd240,
      parameter START_X = 9'd320,
      parameter START_Y = 9'h0
    )
 (
    input wire clk,
    input wire er_dil,
    input wire [0:0]     data_in,
    input wire             input_valid,
    input wire [10:0]    x_in, y_in,        
    output wire            output_valid,
    output wire    [0:0]     data_out
);

localparam END_X = (WIDTH + START_X) - 1;
localparam END_Y = HEIGH - 1;

wire e_bound, s_bound, n_bound, w_bound;

assign n_bound = (y_in == START_Y && x_in == START_X) ? 1'b1 : 1'b0;
assign s_bound = (y_in == END_Y && x_in == END_X) ? 1'b1 : 1'b0;
assign w_bound = (x_in == START_X) ? 1'b1 : 1'b0;
assign e_bound = (x_in == END_X) ? 1'b1 : 1'b0;

// stage 1
wire mux1_out, mux2_out;
wire [2:0] mux3_out;
wire [2:0] mux4_out;
reg  [2:0] ff = 0;
reg  [2:0] ff_d = 0;
wire [2:0] sum1;
wire [2:0] mux5_out;
wire cmp1_out;
wire [8:0] mem_addr = input_valid ? x_in[8:0] - START_X : 9'd0;

assign mux1_out = er_dil ? ~data_in : data_in;
assign mux2_out = (e_bound | s_bound) ? 1'b1 : mux1_out;
assign mux3_out = mux2_out ? sum1 : 3'h0;
assign mux4_out = cmp1_out ? mux5_out : mux3_out;
always @(posedge clk) ff_d = mux4_out;
always @* ff = ff_d;
assign mux5_out = w_bound ? BH - 1'b1 : ff;
assign sum1 = mux5_out + 1'b1;

assign cmp1_out = (mux3_out == BW) ? 1'b1 : 1'b0;

// stage2 2
wire [2:0] sum2;
wire [2:0] mux6_out, mux7_out;

wire cmp2_out;
wire [2:0] mux8_out;
wire [2:0] mem_out;

alt_ram320x3 row_mem (
    .clock(clk),
    .data(mux7_out),
    .rdaddress(mem_addr),
    .wraddress(mem_addr),
    .wren(1'b1),
    .q(mem_out)
);

assign mux6_out = cmp1_out ? sum2 : 3'h0;
assign mux7_out = cmp2_out ? mux8_out : mux6_out;
assign mux8_out = n_bound ? BW : mem_out;
assign sum2 = mux8_out + 1'b1;

assign cmp2_out = (mux6_out == BH) ? 1'b1 : 1'b0;
assign data_out = er_dil ? ~cmp2_out : cmp2_out;
assign output_valid = input_valid;
endmodule



Операции открытие и закрытие:
opening/closing
wire [0:0] er1_out, dil1_out, er2_out, dil2_out;
wire dil_input = line_data_out;

// OPENING
// EROSION 3x3
    low_complexity
    #(
        .BW(3'h3), .BH(3'h3),
        .WIDTH(9'd320), .HEIGH(9'd240),
        .START_X(9'd320), .START_Y(9'h0)
    ) er_1 (
        .clk(clk),
        .er_dil(1'b0),
        .data_in(dil_input),
        .input_valid(line_rd_rq),
        .x_in(x_in),
        .y_in(y_in),        
        .output_valid(),
        .data_out(er1_out)
    );
    
    
    // DILATION 3x3
    low_complexity
    #(
        .BW(3'h3), .BH(3'h3),
        .WIDTH(9'd320), .HEIGH(9'd240),
        .START_X(9'd320), .START_Y(9'h0)
    ) dil_1 (
        .clk(clk),
        .er_dil(1'b1),
        .data_in(er1_out),
        .input_valid(line_rd_rq),
        .x_in(x_in),
        .y_in(y_in),        
        .output_valid(),
        .data_out(dil1_out)
    );
    
    // CLOSING
    // DILATION 3x3
    low_complexity
    #(
        .BW(3'h3), .BH(3'h3),
        .WIDTH(9'd320), .HEIGH(9'd240),
        .START_X(9'd320), .START_Y(9'h0)
    ) dil_2 (
        .clk(clk),
        .er_dil(1'b1),
        .data_in(dil1_out),
        .input_valid(line_rd_rq),
        .x_in(x_in),
        .y_in(y_in),        
        .output_valid(),
        .data_out(dil2_out)
    );
    
    // EROSION 3x3
    low_complexity
    #(
        .BW(3'h3), .BH(3'h3),
        .WIDTH(9'd320), .HEIGH(9'd240),
        .START_X(9'd320), .START_Y(9'h0)
    ) er_2 (
        .clk(clk),
        .er_dil(1'b0),
        .data_in(dil2_out),
        .input_valid(line_rd_rq),
        .x_in(x_in),
        .y_in(y_in),        
        .output_valid(),
        .data_out(er2_out)
    );


Результат


На этом видео демонстрируется эффективность фильтрации изображения методом математической морфологии (low complexity method) с окном 3x3 в сравнении с медианным фильтром с окном того-же размера.

Зелёный маркер — медианный фильтр
Жёлтый маркер — морфология

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

Выводы


На основе метода low complexity erosion/dilation можно построить базовые элементы морфологической обработки изображения много эффективнее по расходу памяти чем при помощи формирования оконной функции.
Результат фильтрации изображения методом математической морфологии ничуть не хуже результата фильтрации медианным фильтром, и является неплохой альтернативой последнему.

Материалы по теме


Low complexity method
Morphological image processing
Математическая морфология

Комментарии (0)

    Let's block ads! (Why?)

    Школа стартапов 2017 от Y Combinator: «Зачем?» (часть первая)

    — Добро пожаловать. Это CS183F, спасибо, что пришли, мы надеемся, это будет очень хороший курс. Мы собираемся попытаться научить вас тому, что вам нужно в первые 100 дней стартапа, по сути, мы научим вас как перейти от сырой идеи к компании.

    Я глава Y Combinator, Сэм Альтман, я учу этих людей уже продолжительное время и надеюсь, мы сможем доступно все объяснить. Сегодня помимо меня в качестве приглашенного спикера выступит Дастин Московиц.

    Дастин является одним из основателей Facebook и CTO и разработчик MVP. Сейчас он сооснователь и CEO Asana. Дастин выступает первым от лица этого курса, и о его выступлении я говорю другим людям чаще всего. Оно о том, зачем начинать стартап и это на самом деле очень важный вопрос, о котором люди недостаточно думают. Он любезно согласился вернуться и рассказать об этом снова.

    — Если вы здесь сегодня или смотрите видео позже, значит, вы, вероятно, планируете создать компанию. Поэтому вы проходите этот курс. Большая часть курса будет о том, как сделать это и добиться успеха. Но прежде чем мы углубимся в то, как стать предпринимателем, я здесь, чтобы помочь понять вам почему.

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

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

    Это не длинная речь, у меня около 10 слайдов и я оставил немного времени на вопросы в конце. Отлично. И так, будем называть вещи своими именами.

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

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

    Только 1% финансируемых компаний проходит через всю воронку. Прохождение шести витков воронки не совсем то же самое, что стать единорогом, но вполне соотносимо. Большинство единорогов, которых я знаю, должны пройти как минимум через такое большое количество витков финансирования. Чтобы этого добиться, нужно иметь по-настоящему замечательную идею. Она должна быть уникальной, оправданной, завоевывающий крупный рынок. Вы должны выполнить ее чрезвычайно хорошо, а это значит, что вы должны усердно работать, вы должны привлечь нужных людей и у вас должна быть стратегия лучше, чем у ваших конкурентов. И вам так же нужно быть очень-очень везучими, потому что много чего может встать у вас на пути, и многое из этого вы не в состоянии контролировать.

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

    Давайте поговорим о двух замечательных способах, которые могут привести вас к чудесной зарплате.

    Первая история: вы основатель, вы создали компанию, которая организует Uber для домашних животных. На картинке клиент, не основатель. Это прекрасная идея и вы хорошо ее выполнили, поэтому в какой-то момент вы продаете компанию за 100 миллионов долларов. Если у вас действительно успешное предельное уменьшение долевого участия акционеров в распределении чистого дохода, ваш капитал будет составлять 10% от компании к тому времени, как она станет ликвидной. Поэтому вы получите 10 миллионов долларов. Довольно прекрасный доход.

    Однако я показал только малую часть начального набора, который позволил зайти так далеко, поэтому это удачный случай. 100 миллионов долларов немного легче, чем 1 миллиард долларов, но это по-прежнему крайне редко случается. Вероятней всего вы останетесь ни с чем на этом пути, потому что вы закроете компанию по какой-либо причине. И часто вы видите компанию проданную покупателю с оценкой такого диапазона. И во множестве случаев основатель все равно остается ни с чем из-за предпочтения ликвидности инвестора. Поэтому многое зависит от того сколько денег вы получили, чтобы добраться до этого. Это определенно очень рискованный путь.

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

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

    Сотый разработчик Facebook имеет гораздо более хорошую зарплату, чем большинство предпринимателей. Конечно, возможно, что вы выберете неверную компанию, не дорастете до такой зарплаты. Это кстати 40х рост, что впечатляет. Но суть в том, что вы должны присоединиться к компании гораздо позже ее цикла развития. У вас будет больше информации. Вы можете увидеть производительность, встретиться с кем-то из команды, понять конкурентную среду. И даже если вы не найдете компанию, которая дорастет до таких высот, у вас есть хороший шанс выбрать ту, которая дорастет до какого-то приличного уровня. На самом деле оценка вашего капитала вероятно уже не равна нулю. Поэтому у вас прекрасные шансы получить хороший результат в таком случае и возможно получить очень хороший заработок.

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

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

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

    Я хочу привести конкретные примеры глобального влияния на мир, которую получали люди в качестве сотрудников. Брет Тейлор, был главой Quip прежде чем стать предпринимателем, после он присоединился к Google, у которых на тот момент уже было более 1000 сотрудников. Тем не менее, он стал инициатором создания Google Maps, которые используются сотнями миллионов людей, включая меня по пути сюда сегодня.

    Подобно этому мой сооснователь Asana, Джастин Розенштайн, присоединился к Google примерно в то же время и сделал прототип G-чата внутри Gmail. Это было более 10 лет назад, но он все еще используется массой людей. И вскоре после этого он пошел в Facebook, у него было несколько сотен сотрудников, и он руководил проектом Хакатона, благодаря которому была изобретена кнопка Like. Некоторые из вас, вероятно, использовали ее один или два раза.

    И так, вы все еще можете присоединиться к таким командам как Facebook и Google на сегодняшний день и работать над чем-то, что может привлечь буквально миллиард людей.

    Если вы хотите стать предпринимателем и максимально увеличить глобальное влияние, это те истории, с которыми вы должны сравнивать свои возможности. Дальше идет образ жизни. У каждого есть своя история касательно того, что значит быть бизнесменом.

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

    Первое изображение здесь из «Социальной сети», это художественный фильм о создании Facebook. Выглядит забавно. И последнее фото это реальное фото создания Facebook. Они немного разные. Реальность это множество моментов с опущенной головой во время тяжелой работы. У нас едва хватает времени на то, чтобы открыть шампанское и обрызгивать ими наши ноутбуки. И так, на практике, технология не совсем такая как в «Социальной сети», скорее как в «Кремниевой долине». Все на самом деле очень стрессовое. Почему так? По многим причинам.

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

    Название слайда здесь это конечно отсылка к книге Бена Хоровитца «Легко не будет». Если вы хотите углубиться в предмет, я определенно рекомендую прочитать это. Так же люди думают, что, будучи основателем, ты можешь контролировать то, как ты тратишь свое время.


    «Люди представляют себе главных исполнительных директоров компании на вершине пирамиды…

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

    Жизнь большинства главных исполнительных директоров заключается в том, чтобы отчитываться перед всеми остальными… Если вы хотите чувствовать всеобщее признание и власть над людьми, идите в военную сферу или в политику. Не становитесь предпринимателями.»


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

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

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

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

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

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

    Вы можете заниматься предпринимательством в контексте существующей компании. Я сам дважды решал стать предпринимателем и оба раза я был мотивирован именно этой причиной. В случае с Facebook мы фактически оставались студентами Гарварда до тех пор, пока сайт не стал собирать более 100 000 активных пользователей в месяц. У нас был когнитивный диссонанс на протяжении очень долгого промежутка времени, когда мы были студентами и у нас был этот маленький проект. Но, в конце концов, мы ушли, так как не могли вынести саму мысль о том, чтобы не воплотить этот проект в полной мере. В какой-то момент мы с Джастином были вынужденными предпринимателями, но мы думали, что проблема, над которой мы работаем, очень важна. И что другие люди, работающие над ней, собирались разрабатывать поэтапные решения, поэтому на кону был очень ценный проект. Мы не могли перестать работать над ним.

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

    — Несколько минут

    — Несколько минут, отлично. Если у вас есть вопросы, поднимайте руки и повторите вопрос в микрофон. Кто-то всегда должен начать, своего рода наблюдение.

    — У меня есть вопрос.

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

    — Есть две вещи. Одна это своего рода особенность, которая не является отличительным признаком компании вроде той, о которой говорили Марк и Тристан. Я не знаю, как озвучить это более конкретно, но я вроде как думаю о самой идее. Я воспринимаю ее как отдельный продукт и решаю, подписался бы кто-то на нечто подобное, может ли эта идея иметь свою модель монетизации? Будут ли люди инвестировать деньги в то, чтобы узнать эту новую систему или она больше воспринимается как дополнение к уже существующей модели? И нечто столь же близкое к этому, о чем стоит думать это конкурентная среда. Если вам нужно представить абсолютно новое приложение для обмена фотографиями, то вам нужно соревноваться с существующими приложениями в распространении и сетевых эффектах, что является огромным препятствием на пути. Существуют также другие метафоры и другие продукты. Понятно?

    — Да.

    — Это часть взгляда на продукт.

    — Давай ты, а потом ты.

    — Мне любопытно, что вы думаете о проблемах создания компании в былые времена и о проблемах создания компании на сегодняшний день впервые?

    — Я своего рода кратко изложил их, когда говорил о воронке. О, простите, вопрос заключался в том, в чем различия в проблемах во время создания компании, например, в 2004 году и создании компании сегодня или во второй раз в 2009 году. Я своего рода изложил их, когда говорил о воронке. Но я определенно думаю, что по сравнению с другими видами бизнесами этот гораздо более конкурентоспособный. Большинство ценных рынков уже имеют интересных игроков. Также высокая конкурентоспособность на рекрутинговых рынках. Очень тяжело получить достаточно большую команду довольно талантливых людей и эти люди будут стоить дороже. Это одна из сфер, в которых подпрыгнули цены, и существует целый ряд других, включая недвижимость, которая очень дорогая на сегодняшний день. Некоторые цены снизились, например, на центры обработки данных, но, в общем, цены выше и соответственно труднее пробиться дальше.

    — Я упомянул сравнение между стартапом, будучи основателем и будучи собой. Как положение или возможно первая попытка людей такого рода влияет?

    — Еще очень много всего в этом диапазоне. Простите, вопрос в том, какова разница между тем случаем, когда ты своего рода поздний сотрудник в существующей компании и тем случаем, когда ты ранний сотрудник? В этом же заключается вопрос, верно? Я думаю об этом как о диапазоне шкалы риска между создателем компании и ее тысячным сотрудником. Если вы в первой десятке, у вас немного больше информации, вы знаете, кто основал эту компанию, вы знаете лидеров. Вы можете встретить кого-то из инвесторов. Надеемся, что они уже прошли первый виток воронки или виток A, но зачастую у вас еще нет данных о доходе или монетизации. И возможно продукт еще не оценен. Это своего рода продолжительный диапазон и чем раньше ты пришел, тем ниже будет твоя зарплата, тем ниже будет вероятность получить положительную отдачу. Но у вас также есть возможность получить очень большой результат, потому что у вас, может, есть 50 основных дел или 100 основных дел, если вы один из первых сотрудников. Понятно?

    — Является ли вероятность успеха между сотрудником и одним из основателей приблизительно одинаковой?

    — Это снова на диапазоне, верно? Вопрос был о том, является ли вероятность успеха приблизительно одинаковой? Для второго сотрудника, да, для десятого сотрудника нет, у них гораздо больше информации. Для 20 сотрудника еще больше информации и это будет непрерывный спектр.

    — Вопрос здесь.

    — Как вы нашли свою основную команду, когда вы основывали Facebook? Это произошло естественным образом или вы выбирали лучшего в каждой области?

    — Разумеется, как же мы нашли основную команду? В Facebook довольно естественным образом, многие люди были как люди из нашей сети в Гарварде, которую мы перенесли на запад Пало-Альто. Еще на ранней стадии мы наняли Марка Коллиера и он занялся вербовкой и помог нам попасть в сети Стэнфорда и многие люди, которых мы наняли, только закончили университет на тот момент. И мы сперва были очень сосредоточены на команде продукта. Многое зависело от пути и естественных рабочих сетей. Сейчас все немного по-другому, в маленькой компании вы не можете работать с подрядчиком, нанимателями и даже с некоторыми сервисами, которые помогают связаться с людьми. И я думаю это очень хорошо. Следующий вопрос.

    — Я раздумывал об измерении энтузиазма. Что вы думаете о стадиях от интереса до патологической одержимости?

    — Вопрос заключается вот в чем: когда я говорил о страсти, говорил ли я только о заинтересованности предметом или о патологической одержимости? Это снова диапазон, но уже по отношению к патологической одержимости. Например, когда я говорю «ты не можешь это сделать», бывает ты оглядываешься назад спустя 20 лет и ты такой «я, в самом деле, должен был ухватиться за эту идею, это было очень важно для меня». Что насчет интереса, меня много чего интересует в мире, но не все из этого обязательно важно и не все будут привлекать мое внимание на протяжении 10 или 20 лет.

    — Что там по времени?

    — Еще один вопрос.

    — Я строю не продукт или идею, всегда ли я должен иметь сооснователя и если да, то как я должен его искать?

    — Вопрос заключается в том, всегда ли у тебя должен быть сооснователь и если да, то как его искать? Это довольно сложный вопрос. Я был убежден, что сооснователи невероятно важны. Снова, потому что это очень сложно и у тебя есть приятель, на которого ты можешь положиться и он с тобой в одной лодке. Но если у вас нет определенного человека, с которым вы хотите работать, я не могу дать хороший совет касательно того, что тогда делать в обоих случаях. Мы создаем компанию вместе, мы обсуждаем ее вместе все время. Вся эта тема с так называемыми «свиданиями» с основателями для меня лишена смысла. Я думаю, создание компании это более важные взаимоотношения, чем женитьба или нечто подобное, потому что финансовые вопросы встают между вами гораздо чаще. И расставания это очень плохо. Я настоятельно рекомендую работать с кем-то, кого вы уже давно знаете и обсуждать как можно больше деталей, чтобы быть уверенным, что вы понимаете друг друга, потому что впоследствии эти разговоры станут гораздо тяжелее. Хорошо, заканчиваем?

    — Спасибо, Дастин. Это было великолепно.

    image

    Продолжение следует

    Кто готов помочь с переводом следующих лекций или улучшением существующего перевода — пишите в личку.

    Полное видео:

    Комментарии (0)

      Let's block ads! (Why?)

      Архаичные алгоритмы сжатия видео эпохи FMV-игр

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

      Но была и проблема: типичное игровое разрешение того времени — 320 на 200 точек при палитре из 256 цветов, что даёт нам 64 килобайта на кадр или полтора мегабайта на 25 кадров, при скорости чтения с компакт диска в 150 килобайт в секунду. Т.е. видео надо было жать и жать довольно сильно, а сжав, потом надо суметь декодировать, ведь мы помним, компы были слабенькие и декодирование, например, MPEG им было вообще не по силам. Тем не менее производители видео игр успешно решили проблему недостаточной производительности породив заодно множество видео-кодеков и игровых видео-форматов, некоторые из которых могли проигрываться аж 286-м (прописью: двести восемьдесят шестым) процессором.

      Так началась эпоха FMV игр (Full Motion Video Games). Я думаю, многие помнят её ярких представителей: Crime Patrol от American Laser Games, Lost Eden, Cyberia, Novastorm и даже Command & Conquer, в который многие играли только ради видеовставок между миссиями. В те времена выглядело это очень круто. Вау! Вау! Ну а мне было интересно, как же они закодировали это видео, в книжках о мультимедиа приводили то же описание проблемы, что и я выше, но ничего внятного о методах сжатия не писали, видимо, авторы в этом мало понимали и пересказывали какие-то сомнительные слухи.

      На самом деле, всё оказалось очень просто, методов было всего три штуки и все очень простые.

      Но перед тем как мы перейдём к самим методам, были ещё повсеместно использовавшиеся ухищрения. Во-первых, конечно, ни о каких 25 кадрах в секунду не могло быть и речи. Все поголовно резали fps, вплоть до 10 кадров в секунду (интерактивные тиры Americal Laser Games). 12, 14, 15 fps — типичные фрэйм рэйты. Во-вторых, конечно же, разрешение картинки резали почти всегда, ведь если с каждой стороны от кадра отрезать по 10 пикселей (по 3%), то это даст ~15% выигрыша. Ну а если разрешение понизить до 256 на 144 точек, как это сделали разработчики Novastorm, то выигрыш составит практически половину.

      И так, смотрите, если взять 256 на 144 точи и 14 кадров в секунду, то это даст нам пол мегабайта несжатого видео вместо полутoра мегабайт, что обнадеживает.

      1. Грубая сила и невежество (RLE, LZ)


      Был такой формат BFI, что расшифровывалось разработчиками как «Brute Force & Ignorance». К этой группе относятся различные облегченные вариации по мотивам RLE и LZ алгоритмов. Это может показаться удивительным, но зачастую этого было достаточно, ну а если например в динамичной сцене сжатия не хватало, то всегда можно начать пропускать кадры, или же ещё сильнее понизить разрешение картинки в два, а то и в четыре раза (MM). Видео в тирах American Lazer Games, играх серии Wing Commander, игре Lost Eden и других играх студии Cryo закодированы именно так.


      Обратите внимание на характерные для Lossy RLE горизонтальные полосы.

      2. Векторное квантование (VQ)


      Идея простая: возьмем скажем восемь идущих друг за другом кадров и нарежем их все на блоки по 4x2 пикселя, при разрешении картинки в 320 на 156 пикслей это даст нам 50 тысяч 24-х мерных векторов (8 пикселей в блоке, три цветовых компонента у каждого пикселя). Идущие друг за другом кадры весьма вероятно имеют много общего, поэтому среди этих векторов окажется множество близких друг к другу. Далее делим эти вектора на 4096 групп, для каждой группы вычисляем центроид. Из центроидов формируем codebook, ну а кадры записываем в файл в виде цепочек 12-и битных ссылок на codebook. Вместе это нам даёт примерно 13 килобайт на кадр, что в принципе по силам для двухскоростного сидирома.

      Примерно такой подход использовался в ранних играх серии Command & Conquer.

      Декодирование, очевидно, очень быстрое и дешёвое, но вот качественно закодировать видео данным методом очень непросто. Не у всех, кто использовал VQ, это получилось хорошо. Вот полюбуйтесь на скриншоты игры Creature Shock.

      3. Block Truncation Coding (BTC)


      Тут опять всё просто, ничего сложного в 90-х не применяли. Чтобы сохранить 256-и цветное изображение нам надо по байту на каждый пиксель. А давайте уменьшим количество цветов, допустим, до двух, теперь на пиксель нужно по биту, мы получили восьмикратное сжатие и картинку кошмарного качества. Что можно с этим сделать? Просто применим данный подход не ко всему изображению целиком, а к небольшим блокам, ведь с большой вероятностью все цвета в рамках достаточно маленького блока близки друг другу. Режем картинку на блоки, скажем, 4 на 4 пикселя и для каждого из них сохраняем два цвета (его персональную палитру) и ещё 16 бит ссылок на эти цвета. Всего 4 байта на блок из 16-и пикселей, т.е. получили 4-х кратное сжатие. Но если вдруг окажется, что двух цветов для данного блока мало, то мы можем сохранить и четыре цвета — это даст нам двукратное сжатие. А можно разделить блок на 4 блока меньшего размера и для каждого из них вычислить по два цвета.

      Этот метод был очень популярен, он прост и быстр в кодировании и декодировании, обеспечивает разумное качество, легко реализуем. В игре Novastorm используются блоки 8 на 8, которые могут иметь палитру из 2, 4, 8 цветов. В известной игре Z тоже используется нарезка на блоки по 8 на 8 пикселей и деление их на части при необходимости (JV). В Cyberia — комбинированный подход: используется как деление на меньшие блоки так и палитры разного размера (C93, M95).

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

      Конечно, все использовали межкадровое сжатие в самом его примитивном виде зачастую даже без предсказания движения. Ни о какой коррекции яркости в палитризованых видео не могло быть и речи, поэтому на сценах с затемнением визуально падала частота кадров. Это очень было заметно в роликах самой первой Need For Speed, а я-то думал, что у меня проблемы с моим 4-х скоростным сидиромом. Даже пытался вернуть его в магазин.


      Кадр из игры Rebel Assault. Блочность, характерные для VQ повторы блоков. Блоки 4 на 4, преимущественно двухцветные, скорее всего codebook дополнительно закодирован с помощью BTC.

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

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

      В статье использованы скриншоты с сайта mobygames.com.

      Комментарии (0)

        Let's block ads! (Why?)

        Бесплатная трансляция главного трека JPoint 2017. Сейчас! Без регистрации и смс

        Всем привет! В прошлом году на Joker 2017 мы делали открытую трансляцию главного зала. В тот раз не обошлось без технических заминок, но в целом зашло хорошо. Мы решили продолжать славную традицию и сделать это еще раз – сегодня с 10 утра мы начинаем бесплатную YouTube-трансляцию первого трека JPoint 2017! Первый трек – самый большой и хардкорный, будут доклады Алексея Шипилёва, Евгения EvgenyBorisov Борисова, Arun Gupta, Сергея Walrus Куксенко и не только

        Если кто не в курсе, вчера успешно прошел первый день международной Java-конференции JPoint 2017: 1200 участников, 25 докладчиков, 20 докладов, 4 трека, – все серьезно. Но пост будет не о прошедшей конференции, а о том, что нам (и некоторым из вас) еще предстоит.

        Под катом – список докладов и ссылка на YouTube.

        Расписание трека и доклады




        Евгений Борисов и Кирилл Толкачёв — Проклятие Spring Test

        Каждая технология содержит определенный набор подводных камней. Знать о них и ловко обходить – задача разработчика владеющего технологий. Spring не исключение. Попробуем разобраться в различных подходах к тестированию на примере Spring Boot приложения, тестируя его шаг за шагом, используя новые фичи и собирая новые грабли. Поговорим про юнит-тестировании, интеграционных тестах, связи Spring MVC с Spring Boot и, конечно, о болях использования Spring 4+.




        Алексей Шипилёв — Shenandoah: сборщик мусора, который смог

        Shenandoah — новый сборщик мусора от Red Hat, который пытается решить проблему перемещения объектов без остановки приложения, сбивая паузы ещё больше. Этот доклад об особенностях дизайна и реализации Shenandoah, достоинствах, которыми можно гордиться, и недостатках, с которыми приходится мириться. Если топите за кишки и перфоманс — вам сюда.



        Николай Алименков — Сделаем Hibernate снова быстрым

        Многие Java-разработчики используют ORM, но большинство из них не знает о существующих опциях для улучшения производительности. C присущей наглядностью и практической ориентированностью, Николай даст обзор этих опций на практических примерах. Доклад практика, а не теоретика.



        Arun Gupta — Deploy your microservice using Amazon Web Services S3, API Gateway, Lambda and Couchbase.

        Live-coding доклад от гуру о создании serverless микросервисов на базе Amazon S3, API Gateway, AWS Lambda и Couchbase. По каждому из представленных элементов будет дан обзор, а в демке Arun покажет, как за час развернуть собственный функциональный микросервис.



        Сергей Куксенко — Повесть о том, как один инженер HTTP/2 Client разгонял

        Доклад о том, как Oracle использует (или не использует) методологии оптимизации производительности, о которых много лет вещали со сцены. На примере «JEP 110: HTTP/2 Client» (который в будущем появится в JDK) Сергей покажет, как команда его запускала, где смотрела и что крутила, чтобы сделать его быстрее. Примечание: доклад не про HTTP/2. Хотя, конечно, некоторых его деталей избежать не удастся.



        Charles Nutter — Going Native: Foreign Functions on the JVM

        Есть много Java-библиотек, привычных большинству разработчиков. Все изменится с приходом Java Native Runtime и Project Panama. Все-таки, кроме существующих Java-библиотек, существует целый мир native-библиотек: для графики, криптографии, интеграции с ОС и многого другого. В этом докладе будут рассмотрены интересные сценарии ухода в native со сравнением возможностей и обзором инструментария для интеграции.

        Трансляция в перерывах


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

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

        Ограничения


        • Поскольку трансляция бесплатная, она предоставляется по принципу as is: мы уверены, что все будет хорошо, но если вдруг что – не обессудьте!
        • Видеозаписей не будет. То есть они, конечно, будут, но только для участников конференции, оставивших фидбек. А для всех остальных мы традиционно выложим их через 3-4 месяца, ближе к Joker 2017.
        • Вы не сможете смотреть, что происходит в других залах. А там будет много интересного. В следующий раз регистрируйтесь и смотрите все без ограничений.

        Всем Java!

        Комментарии (0)

          Let's block ads! (Why?)

          Первые шаги с Gantry 5

          Грамотная посадка верстки на CMS WordPress – задача важная (после нескольких проектов мне стало ясно, что это занимает достаточно много времени). Чтобы ускорить процесс, начал искать фреймворк для написания тем WordPress. О Gantry 5 узнал от коллеги, который ведёт сайты на Joomla. Он рассказал, что есть движок, который может работать, как и на WordPress, так и на Joomla (а с некоторых пор и на Grav). Вот и решил узнать о нём побольше. Ведь согласитесь, — это хорошо: работать с одной системой и, перейдя на другую, продолжить пользоваться теми же инструментами.

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

          Прочитав всё, что смог найти в русскоязычном интернете и частично документацию, решил изучить Gantry 5. Использование в качестве шаблонизатора twig, и хранение конфигов в yaml формате стало дополнительным плюсом (поскольку я давно присматривался к symfony, но времени не находил – получалось частичное изучение инструментов).

          Возможности


          Существует несколько статей об основных возможностях Gantry 5. Описывают они их недостаточно подробно, но что за что отвечает понять можно (правда, с точки зрения пользователя). Увы, о том, как строить шаблон, в них не нашлось ни строчки. Поэтому постараюсь описать инструменты, взяв за основу разработку темы.

          Основные термины


          Частица — основной строительный материал. Проще — это 1 модуль. Они бывают трех типов:
          • Стандартная частица – модули, которые позволяют выводить на страницу данные с учетом параметров самой частицы (какие данные она будет выводить, зависит от самой частицы).
          • Позиция – частицы, которые содержат основную информацию, возвращаемую системой в запросе. Например, текст статьи или список товаров магазина.
          • Атомы — скрытые элементы, скрипты. Например, Google Analytics.

          Gantry 5 использует большое количество собственных типов полей. Ознакомится с их списком и функционалом можно здесь (увы, только английская документация)

          Файловая структура (Hydrogen)


          image

          Hydrogen — это базовый шаблон Gantry 5, который можно скачать здесь. Рассказывая о структуре шаблона, я буду ориентироваться на него (собственные шаблоны стоит создавать по данному образу и подобию).

          /admin/ — переопределение системных файлов (крайне не рекомендуется) и некоторые материалы которые могут быть использованы в админке (например, изображения).

          /blueprints/ — каталог может содержать три директории style, content, page.

          image

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

          /config/ — вроде какие-то конфиги, но сколько не пытался экспериментировать, не смог определить для чего они и какую роль несут.

          /fonts/ — шрифты, которые будут использованы. По умолчанию Gantry 5 тянет их из Google. Чтобы избежать этого, сюда можно положить используемые шрифты.

          /gantry/ — каталог, в котором хранятся файлы описания темы в формате .yaml (описание темы и вариации цветовых схем).

          /images/ — каталог с изображениями темы, их можно будет использовать при кастомизации темы.

          /includes/ — каталог с файлами, отвечающими за взаимодействие темы с Gantry 5.

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

          /layouts/ — каталог для хранения шаблонов разметки. По умолчанию определено 3 обязательных шаблона “Body only”, “Error” и “Offline”.

          /particles/ — каталог для хранения собственных частиц. Для определения новой частицы в нем должны лежать 2 файла {название}.yaml и {название}.html.twig. Первый описывает конфигурацию частицы, второй отвечает за её рендер.

          /scss/ — каталог для scss файлов, которые Gantry 5 будет компилировать.

          /views/ — каталог с twig шаблонами.

          Как создать шаблон


          В интернете смог найти 2 способа работы с шаблонами на Gantry 5:
          1. Создать дочернюю тему на базе облегчённой Hydrogen, которую разработали сами RocketTheme. Этот способ они и предлагают использовать.
          2. Описывать всю тему внутри каталога /custom/, который появляется после первого сохранения Hydrogen темы. Этот каталог не обновляется при выходе новой версии темы, и его данные не потеряются. Но я считаю это непрофессиональным, потому что /custom/ по сути является кэшем наших данных, туда сохраняются все наши настройки. Получается, что фактически работа идёт во временном хранилище, и отдавать такое заказчику как-то некрасиво.

          Благодаря старой поговорке (хочешь сделать хорошо, сделай это сам) был выбрантретий путь.

          Я создал отдельную чистую тему и научил её работать с Gantry 5 (благо это не очень сложно). К тому же у этого подхода есть преимущество: я зашил в тему TGM Plugin Activation, включил в него плагин Gantry 5 и сделал его обязательным. Таким образом при активации темы сразу будет установлен необходимый плагин (плюс – сюда можно вложить еще много полезного).

          Начнём по порядку


          Инициализация

          Создаём каталог для темы WP и в нём три файла index.php, style.css, functions.php. Копируем из темы hydrogen папки includes и gantry (в этой директории лежат два файла — один с персетами, второй с опциями темы, используем их как основу для описания своих конфигов). В style.css инициализируем тему, а в файл functions.php добавляем следующий код:

          //*****************************//
          //Gantry
          //*****************************//
          {
                  // Минимальная версия плагина Gantry 5
                  $requiredGantryVersion = '5.4.0';
          
                  // Для инициализации Gantry 5
                  $gantry_include = get_stylesheet_directory() . '/includes/gantry.php';
          
                  //На случай если тема является дочерней проверим наличие файла в родительной
                  if ( ! file_exists( $gantry_include ) ) {
                          $gantry_include = get_template_directory() . '/includes/gantry.php';
                  }
                  $gantry = include_once $gantry_include;
                  if ( ! $gantry ) {
                          return;
                  }
          
                  // Проверяем минимальную версию Gantry
                  if ( ! $gantry->isCompatible( $requiredGantryVersion ) ) {
                          $current_theme = wp_get_theme();
                          $error         = sprintf('Please upgrade Gantry 5 Framework to v%s (or later) before using %s theme!',
                                  strtoupper( $requiredGantryVersion ), $current_theme->get( 'Name' )
                          );
          
                          if ( is_admin() ) {
                                  add_action(
                                          'admin_notices', function () use ( $error ) {
                                          echo '
          

          ' . $error . '

          ';
                                  });
                          } else {
                                  wp_die( $error );
                          }
                  }
          
                  /** @var \Gantry\Framework\Theme $theme */
                  $theme = $gantry['theme'];
          
              // Подключаем файлы со вспомогательными функциями и хуками которые могут быть полезны в теме
                  $helpers = array(
                          'includes/helper.php', // Основной файл с хуками должен быть всегда
                  );
          
                  foreach ( $helpers as $file ) {
                          if ( ! $filepath = locate_template( $file ) ) {
                                  trigger_error( sprintf( 'Error locating %s for inclusion', $file ), E_USER_ERROR );
                          }
          
                          require $filepath;
                  }
          }
          

          После этого тема уже будет работать с Gantry 5.

          Да, я собрал тему сам, но учился на Hydrogen и использовал его как базу. И теперь точно уверен в теме и её работоспособности, знаю где смотреть, если что-то сломается.

          Режим разработки

          image

          Первое на что стоит обратить внимание при открытии административной панели Gantry 5, — это режим разработчика. При разработке темы он должен быть всегда включён.

          В Gantry 5 встроен препроцессор scss, который позволяет компилировать файлы стилей на лету. Причём компиляция устроена таким образом, что препроцессор может использовать в качестве переменных значения полей Gantry 5. Например, в /blueprints/styles/body.yaml есть поле, отвечающее за цвет, и менять background у body требуется с его помощью. В scss прописывается код:

          //Имя переменной складывается из названия файла body и имени поля, из которого берутся данные
          //необходимо создать переменную с дефолтным значением
          $body-color-1: #ffffff;
          body{
                  background: $body-color-1;
          }
          
          

          При компиляции если в админке установлен цвет, то background будет перекрашен в него, если нет, то будет использован дефолтный, установленный в нашем файле.

          Если необходимо использовать такие настройки в частицах, их следует прописывать в twig-шаблоне частицы через атрибут style.

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

          Кроме того, Gantry 5 позволяет создать несколько заранее предустановленных цветовых стилей. Тут и добавить нечего: выбирается одна схема — цвета одни, выбирается другая — цвета меняются.

          Вот так при компиляции Gantry 5 создает css-файл, который использует в дальнейшем (в разработке постоянно пересобирать файл неудобно, так как требуется выполнить множество действий). Вот для этого и нужен режим разработки. При каждом обновлении страницы он собирает новый файл стилей.

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

          Шаблоны разметки

          Адаптивность в Gantry 5 строится на системе разметки Nucleus. Файлы стилей расположены по адресу “ROOT/wp-content/plugins/gantry5/engines/nucleus/”. В шаблон, в scss необходимо обязательно подключить 4 файла:

          @import "vendor/bourbon/bourbon";
          @import "configuration/nucleus/base";
          @import "nucleus/functions/base";
          @import "nucleus/mixins/base";
          
          

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

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

          image

          Шаблоны разметки описываются в директории {директория темы}/layouts. После конфигурирования разметки страницы шаблон появляется в Административной панели, и его можно использовать для компоновки частиц.

          Вот пример описания шаблона default.yaml:

          version: 2
          #Изображение
          preset:
            image: gantry-admin://images/layouts/default.png //изображение из директории /admin/
          #Позиции для вставки частиц. В шаблоне можно предопределить некоторые из них
          layout:
            /header/:
              - [logo 30, position-header 70]
          
            /navigation/:
              - menu
          
            /main/:
              - position-breadcrumbs
              - system-messages
              - system-content
          
            /footer/:
              - position-footer
              - [copyright 40, spacer 30, branding 30]
          
            offcanvas:
              - mobile-menu
          
          

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

          Подробнее о частицах

          При установке плагина Gantry 5 по умолчанию доступно 11 частиц, 5 позиций, 4 предустановленных атома. Если нас не устраивает их поведение, мы всегда можем их переопределить и научить том, что нужно нам.

          Простые частицы

          Сама по себе частица представляет отдельный самостоятельный модуль, который может быть выведен в любое место шаблона страницы.
          В большинстве случаев хватает обычного набора частиц, но что если потребуется создать непохожую ни на одну частицу (например, вывод адреса или телефона)? Всего-то потребуется создать два файла в директории particles (например, phone.yaml и phone.html.twig). В первом описывается конфигурация частицы, во втором — шаблон вывода. В phone.yaml необходимо описать частицу, указать её название, описание, тип particle(atom, position) и иконку (Font Awesome).

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

          Общие впечатления


          Респонсивность, частицы, удобная админка, интересные решения, высокая скорость работы (потому что все конфиги хранятся в файлах), возможность работать на WordPress, Joomla, Grav и технологии, которые, казалось бы, не стоит использовать в WordPress, сделали этот фреймворк просто открытием.

          После углублённого знакомства с технологией не понимаю, почему о ней так мало известно.

          На данный момент единственными минусами Gantry 5, которые я смог увидеть, являются английская документация (хотя это с какой стороны посмотреть) и недостаток информации о фреймворке в нашем сегменте интернета.

          Небольшое заключение


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

          Комментарии (0)

            Let's block ads! (Why?)

            пятница, 7 апреля 2017 г.

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

            Предлагаю пятничные апрельские тезисы про Что наша жизнь? Игра...

            Здесь нет кода и смысла, нет математики и ссылок на GitHub.
            Короче, самый то, чтобы не читать. Но ты прочти.

            А началось все с этой морды


            .

            Вернее сказать, началось все с этой строки

            10 CLS

            30 лет назад эта команда очистила экран IBM PC/XT.
            Я, как зачарованный, смотрел на потухшие 320 на 200 черных точки и понимал, что теперь могу их зажечь, как звезды на небе. Простой командой. Простой парень. И я зажег. Так зажег, что до сих пор остыть не могу.

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

            Пофик! До этого вся анимация, созданная мною, умещалась в 50 страницах маленького блокнота. Мы рисовали внизу каждой страницы человечка, выпускающего стрелу, стрела летела и поражала другого человечка. Потом страницы блокнота пролистывались большим пальцем правой руки — вжи-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-и-к, и 50 кадров мультика вызывали одобрительное гуканье. Было клево. Самые красивые девчонки школы просили блокнотик. Мягко клали руку на плечо и заглядывали в глаза. Стоп, я тону. Лучше вернемся к басику.

            Так вот, первая сделанная игра на BASICе называлась Челюсти. Челюсти сжимались и разжимались. Конфигурация зубов менялась. Герой бегал внутри пасти, ел фрукты и пытался не попасть на зубок.

            Короткое видео геймплея

            Прошло время. Очень быстро.
            Проскочили компилятор для BASIC, Pascal, С, С++, JS, Obj-C и Swift.
            Я делал игры на всем, что втыкается в розетку, и это были в том числе очень даже 3D симуляторы танкового полигона для Муромского/Арзамасского (тсс! строгая тайна!) завода бронетранспортеров и что только не было, лучше и не вспоминать.

            И вдруг вчера мне приснилась та, первая игра.
            Представляете? Ну, что бы вы сделали на моем месте? И я такой же.
            200 строк кода — и, опта! игра лежит в магазине, а код на GitHub-е.

            Что изменилось за 30 лет? Изменилось программирование — раньше челюсти сжимались в цикле все с большей и большей частотой, пока не достигали скорости отрисовки изображения. И если компьютер был слабый — игрок жил бесконечно. Теперь все иначе. Циклов нет. Такты бешеные. А для расчета частоты схлопывания челюсти используют математику. Пусть простую, но интересную. Переходим к выводу формулы частоты движения челюсти.

            Формулировка задачи


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

            Итак что мы имеем?
            1) Устанавливаем время обновления экрана iPhone в 50 герц. То есть 50 раз в секунду. 50 тиков на секунду. Запомним.
            2) Предельная реакция игрока. Вспомним, спринтер на старте забега реагирует на выстрел с задержкой 280 миллисекунд — за это время сигнал проходит путь от его мозга до его же икроножных мышц. iPhone-юзер посылает сигнал не ногам, а своим щупальцам, путь нервного сигнала нервного нерда короче вдвое, =140 миллисекунд — это минимальное время реакции. 7 тиков. Герою игры надо пробежать от края до края челюсти за 6 тапов. То есть минимум 6 тиков. Итого — челюсти, в пределе, не могут сжиматься быстрее, чем за 6+7=13 тиков.
            3) Начальная скорость челюстей — 1 щелк за 50 тиков. Если челюсти будут слишком медленно двигаться — пользователь бросит игру. Поэтому уже через 5-10 секунд частота должна быть 1 щелк в 25-35 тиков.

            Решение.
            Имеем нелинейную функцию
            f(0) = 50
            f(10) = 30
            f(10^10) = 13

            Без дураков ясно — это гипербола.
            Записываем формулу
            f(t) = A + B*(C+t)

            Три неизвестные — три уравнения, решаем (просто удовольствие решать школьные задачки).
            Ответ записываем в листинг программы.

              func setupDelay(_ ticks:Int) {
                    let t = Double(ticks)
                    let a:Double = 12.0
                    let b:Double = 9000.0/2.2
                    let c:Double = 100.0/2.2
                    let d:Double = a + b/(c+t)
                    delay = Int(d)
                }
            
            

            Играть интересно на пределе человеческих способностей.
            Поэтому для тех, кто набирает более 1000 очков, реклама пропадает.
            Жалко же парней.

            Хвала пуно, брате!

            Прим. перев. Код на GitHub разумеется тяп-ляп, но картинки, звуки и некоторые приемы безусловно будут полезны начинающим swift-оманам.

            Комментарии (0)

              Let's block ads! (Why?)

              [Из песочницы] .NET Managed + C unmanaged: какова цена?

              Приглашаем на Imagine Cup: 15 апреля 2017 г. состоится российский финал конкурса

              Друзья! Мы приглашаем вас 15 апреля на российский финал нашего главного студенческого конкурса программных проектов — Imagine Cup! (регистрация, онлайн-трансляция)

              В этом году Imagine Cup исполняется 15 лет. За все эти годы конкурс видоизменялся, в нём появлялись новые категории, он путешествовал по миру, пока не обосновался в Сиэтле. В этом году мы снова вернулись «к истокам», и рассматриваем на конкурсе студенческие проекты любой направленности, использующие современные облачные технологии, при этом основной упор делается именно на технологичности.

              Но кое-что поменялось. Приходите 15 апреля в Digital October, чтобы узнать шокирующие новости об изменениях в Imagine Cup, сколько команд поедут представлять Россию на конкурсе в Сиэтле, а также чтобы отпраздновать вместе с нами! А если не можете прийти — смотрите онлайн-трансляцию!

              Основное, зачем стоит приходить на российский финал — послушать выступления команд! В этом году на финале будет представлено 13 команд, тщательно отобранных из более чем 100 заявок в ходе очного и заочного региональных финалов. В финал вошли команды из МФТИ, Skoltech, Иннополиса, МАИ, МЭИ, ННГУ, ПФУ, ЮФУ, ЮУрГУ, а также один школьный проект. Вы можете заранее ознакомиться с описаниями проектов. Можно послушать выступления команд со сцены, или пообщаться с ними на выставке.

              Среди проектов — система выявления и анализа научных трендов, умные игры для детей, использующие технологии искусственного интеллекта, приложения для выбора интересных туристических маршрутов на основе данных из соцсетей, проект реабилитации после инсульта с Kinect, игра на гитаре на основе умных часов, несколько проектов с виртуальной и дополненной реальностью. Интересно? Очень!

              Кроме выступлений команд, вас ждут:

              • Элитный мастер-класс по машинному обучению с Azure ML и глубокими нейросетями от нашего евангелиста Евгения Григоренко. Это прекрасный шанс за 2 часа познакомиться с такой популярной сейчас темой, как глубокое машинное обучение и научиться на практике распознавать изображения. Для участия в мастер-классе необходимо иметь с собой ноутбук!
              • Интерактивная дискуссия на тему разума и чувств в эпоху искусственного интеллекта. Как вы думаете, скоро ли появятся влюбленные роботы? Ответы принимаем на мероприятии!
              • Секретный мастер-класс / деловая игра, о которой мы пока вам не скажем, но она обещает быть очень интересной!
              • Выставка, где помимо проектов студентов будут представлены интересные устройства, в том числе те, которые вы наверняка захотите увидеть!
              • Ботоквест на знание истории Imagine Cup! Приходите подготовленными, чтобы выиграть призы прямо на месте!
              • Грандиозное закрытие и церемония награждения с участием известного блоггера, с которым вы обязательно захотите сфотографироваться, а также специальный сюрприз, посвященный 15-летию Imagine Cup!
              • Возможность пообщаться с экспертами, узнать о том, где найти ресурсы для развития своих технологических проектов
              • Ну а также как всегда — вкусные кофе-брейки и другие развлечения!

              Надеюсь скоро встретить многих из вас на мероприятии! Спешите зарегистрироваться, места стремительно заканчиваются!

              Комментарии (0)

                Let's block ads! (Why?)

                Surf Studio: машинное обучение в production


                Представляем гостевой пост от компании Surf Studio (Certified Google Developer Developer Agency).

                Привет, Хабр. Меня зовут Александр Ольферук (@olferuk), я занимаюсь машинным обучением в Surf. С 2011 года мы разрабатываем мобильные приложения для крупного бизнеса, а теперь готовим к релизу B2B-продукт с TensorFlow. Спасибо коллегам из Google за возможность рассказать немного о нашем опыте.

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

                Задача


                Задача нашей системы — предсказывать оптимальную наценку на товары розничной сети, имея трехлетнюю историю продаж. Цель — сделать бизнес клиента более прибыльным, конечно же. Данные агрегированы по неделям: известны технические характеристики товаров, сколько единиц товара было продано, в скольких магазинах товар есть в наличии, цены закупки и розницы, а также прибыль, полученная в итоге. Это сырые данные, на продажи влияет еще множество факторов. Все остальные признаки, начиная от инфляции и цен на сырье, и заканчивая погодой, мы собрали самостоятельно. Перед нами был каталог с более чем 20 000 товаров. Из-за различия в их типах мы пришли к построению не одной, а сразу семейства моделей. Каждая из них тренируется на истории о товарах, с точки зрения продаж ведущих себя одинаково.

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

                Ось X здесь — время, разбитое по неделям. Y — нормированная величина, включающая прибыль (синяя линия) и количества продаж (оранжевая линия) Поскольку они почти совпадают, в нашей задаче мы можем опираться или на любую из них.

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

                Как начать проект?


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


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

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

                Pipeline


                После выбора метрики и кросс-валидации усилия команды должны быть брошены на то, чтобы как можно раньше реализовать end-to-end структуру.

                "
                Структура на схеме постоянна и не должна меняться с развитием проекта. На первых порах лучше ограничить очистку данных хотя бы борьбой с отсутствующими значениями: для большинства классификаторов критично отсутствие NaN-значений в данных. Отложить следует также трансформацию признаков и добавление новых.

                После этого нужно выбрать baseline-модель, например решающий лес. Используйте ее для формирования первой отчетности. Ответьте на два вопроса: «Что хотел бы видеть заказчик?», «Какого рода результаты будут понятны и полезны экспертам предметной области?». Отчеты и необходимые графики формируйте исходя из ответов на эти вопросы. В ходе дальнейшей разработки стоит возвращаться к этому шагу, заново отвечать, сохранять ответы, анализировать прогресс.

                Мы же на практике получили систему с формируемой отчетностью достаточно поздно. Поэтому наглядно посмотреть положительную динамику в развитии модели весьма затруднительно.

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

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

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

                От таких библиотек, как sklearn-pandas или luigi, мы отказались. Фактически мы написали собственный велосипед. Это небольшой и очень сырой хелпер, который мы сделали исключительно для себя. В ближайшее время причешем, но пользоваться можно уже сейчас. Мы постарались сделать прозрачный и емкий интерфейс с учетом перечисленных выше особенностей.

                Вот несколько примеров-этапов из нашего пайплайна.

                Добавляем цены на металл, а также цены с лагом в 1 и 2 месяца:

                ('add_metal', DFFeatureUnion([
                    ('metal', DFPipeline([
                        ('load_metal', MetalAppender()),
                        ('metal_lag', Lagger([4, 8]))
                    ]))
                ]))
                

                И еще один:
                ('lags', Lagger(columns_strategies={ 
                    'Z': { 'lags': [1, 2], 'groupby': 'name' },
                    'X': { 'lags': [1], 'groupby': 'name' },
                    'Y': { 'lags': [1], 'groupby': 'name' },
                    'markup': { 'lags': [1], 'groupby': 'name' }
                }))
                

                Здесь логика несколько сложнее, чем просто сдвинуть колонку оператором shift из коробки Pandas. Мы должны учесть, что каждый из признаков сдвигается только для конкретного товара, а не во всей таблице разом. Для того, чтобы решить эту проблему, и был создан класс Lagger.

                Модель разработки


                Дальнейшее развитие проекта идет по спиралевидной модели разработки. Если у вас есть новые идеи: подключение новых признаков или другой способ обработки имеющихся — проверяйте. С выстроенной архитектурой проверка каждой вашей гипотезы будет выглядеть так:
                1. Модифицируем пайплайн обработки данных, вносим необходимые изменения;
                2. переучиваем estimator, подбираем оптимальные гиперпараметры;
                3. вычисляем новый score для полученного классификатора;
                4. визуализируем результаты, формируем отчетность, сравниваем, делаем выводы.

                Небольшое уточнение по третьему пункту. Стоит обратить внимание не на абсолютные значения метрики, а только на ее изменение. Мало того: нельзя доверять этой разнице, если в масштабах вашей выборки все укладывается в рамки случайного отклонения.

                Есть хорошие гайдлайны по организации проекта. Можете ознакомиться с этим и этим, например.

                Если открыть папку проекта, то вот, что мы увидим внутри:

                project/
                ├── data/               <- исходные предоставленные клиентом данные
                ├── cache/              <- pickle-файлы со всякой всячиной
                ├── notebooks/          <- тетрадки
                ├── scripts/            <- *.py-скрипты с протестированным кодом
                ├── logs/               <- логи
                ├── out/                <- все обработанные данные, в том числе:
                    └─ reports/ <- отчеты, в нашем случае xls-файлы
                    └─ plots/   <- графики, в нашем случае сделанные в plotly
                ├── requirements        <- список всех зависимостей проекта
                └── README.md
                

                Как разделить таски между членами команды, чтобы работать, не мешая друг другу? Мы пришли к такой схеме: в рабочей директории есть набор Jupyter-тетрадок, Python-скрипты и сами данные: кэш, отчеты, графики. Каждый работает в отдельной тетрадке. Думаю, не нужно говорить, что тетрадь должна быть хорошо прокомментирована, а все вычисления в них воспроизводимы.

                Сколько нужно таких тетрадок и насколько большими они должны быть? Из нашего опыта — отдельная тетрадь для каждого эксперимента. Пример: «Проверка необходимости внедрения доверительного интервала для предсказаний». Это включает в себя как необходимый код логики, так и визуализацию. Опять же, хорошо и посмотреть, что советуют другие.

                Как только эксперимент завершен и гипотеза проверена — все необходимые функции тестируются и отправляются в Python-скрипты. Если эксперимент себя оправдал, конечно.

                Визуализируй это


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

                • Для визуализации отсутствующих значений пользовались библиотекой MissingNo.
                • Для того, чтобы оценить характер распределения признака, мы пользовались гистограммами: violin plot (его предоставляет, например, библиотека seaborn), box plot. Зачем это нужно?

                • Характер распределения подсказывает, как поступить с отсутствующим значением: для скошенных вполне подойдет заполнение модой, но в случае нормального распределения следует воспользоваться матожиданием.
                • Скошенные данные данные нужно обрабатывать соответственно. Например, использование логарифмирования или нахождение корня N-й степени делает распределение признака более похожим на нормальное. Обычно это помогает увеличить точность.

                • Для оценки важности признака использовали factor plot.
                • Для оценки попарной корреляции признаков использовали correlation matrix и scatterplot matrix. Цель — найти сильно коррелированные признаки и исключить схожие, если такие имеются. Явно значимой пользы для классификатора они не несут, лишь увеличивают дисперсию предсказаний.


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

                Переезжаем в облака с Google


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

                Для этого мы можем:

                • выбирать лучшие признаки;
                • добавлять новые;
                • искать лучшие гиперпараметры моделей.

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

                У нас решение созрело сразу: переезжаем в Google Cloud. От DataLab нам, однако, пришлось отказаться: поддерживается только Python версии 2.7. В рамках задачи нам не требовалась богатая инфраструктура, нам нужна была очень мощная виртуальная машина, а JupyterHub мы можем развернуть и сами.

                На удаленной машине создали несколько директорий: общую и отдельные для каждого члена команды. Это позволило каждому не только работать в общей среде, но и при желании организовать собственный git flow в отдельном разделе. Безопасности ради все ходили исключительно по https, ssh-сертификат тоже сделали.

                Из интересного: скрипты Google для старта виртуальных машин написаны на Python 3.5 и не хотели дружить с нашим Python 3.6. К счастью, все оказалось решаемо.

                Стоила ли игра свеч? Безусловно! Чтобы перебрать все гиперпараметры для пайплайна простым рабочим компьютерам требовалась пара дней. В облаке Google все оказалось гораздо быстрее. Уходишь с работы домой? Пришел утром и все уже готово.

                Что в итоге?


                Из ERP-системы клиента (1С, SAP, Oracle и другие) по требованию можно выгружать исторические данные о продажах. Группа товаров, для которой нужно сформировать прогнозы, обозначена отдельно. Добавляем дополнительные данные, собранные из открытых источников.


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

                Клиент может корректировать ценовую политику на основе полученных прогнозов.

                А/B-тест по-хардкору


                Чтобы показать бизнесу, что умные машины могут не только распознавать картинки с арбузами и писать забавные стихи, нужны результаты. Пока в индустрии широко известных результатов нет, все будут с большим опасением смотреть на подобные решения.

                Нам очень повезло с клиентом. Они поверили в новую для них технологию и дали нам важный шанс — провести хардкорнейший A/B-тест. Нашему коду доверили формировать рекомендации по ценам на все товары сети в целом регионе. Итоговые данные сравним с данными по регионам, где цены формируются по старинке. Если все будет хорошо — будем гордиться тем, что немножко изменили мир, сделали свой скромный вклад в индустрию и проникновение машинного обучения в бизнес. Скрестите за нас пальцы?

                В завершении


                Помните, что простые решения часто оказываются лучшими, а лучший код — чистый.
                Чистите зубы дважды в день.
                Перечитайте МакКонелла.
                Кроссфит и ставки на спорт не стоят потраченного времени.
                Проводите больше времени с семьей.
                Удачи, счастья, здоровья!

                Комментарии (0)

                  Let's block ads! (Why?)

                  [Из песочницы] Web приложение реального времени для простых устройств

                  Об опасностях беспроводных клавиатур и мышей

                  За закрытой дверью фронтенда ЕФС

                  Как привести на сайт посетителей честными способами и сэкономить: дайджест полезных материалов для начинающих

                  Предприниматели, которые запустили первый бизнес в интернете не всегда легко разобраться с тонкостями его продвижения — в результате они расходуют маркетинговый бюджет без должных результатов. И даже тем, кто вроде бы неплохо знаком с онлайн-маркетингом далеко не всегда удается избежать ошибок.

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

                  Советы по привлечению трафика


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

                  Повышение конверсии


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

                  Ошибки продвижения


                  В заключение, ниже я собрал статьи, авторы которых рассказывают о реальных ошибках в продвижении бизнес-сайтов:

                  Комментарии (0)

                    Let's block ads! (Why?)

                    14 инструментов, которые будут полезны для продвижения сайта

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

                    Аналитика


                    Fullstory

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

                    Grade My Ads

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

                    Keywords Everywhere

                    Расширение для браузеров Firefox и Chrome, которое моментально предоставляет информацию о трафике, конкурентности и стоимости за клик для любого ключевого слова, которое вы вводите в строку поиска. Вы также можете подключить выделение цветом для тех вариантов, значения у которых попадают в заданный спектр, в настройках для ускорения отбора, сохранять их и выгружать. Сервис работает с такими сайтами, как Google.com, Google Search Console, Google Analytics, Google Trends, Google Search, UberSuggest, AnswerThePublic.com, Soovle.com, KeywordShitter.com.

                    Serpstat

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

                    Обратная связь


                    chatform.ai

                    Mike Gozzo предлагает остроумный способ сделать опросы менее скучными и более удобными для пользователя. С сервисом chatform.ai стандартные формы-анкеты, от которых все стараются по возможности отмахнуться, уступают место чат-опросам. Связывясь с пользователем через окошко любой популярной системы обмена сообщениями (Facebook Messenger, WeChat, Telegram, LINE, Viber), чатбот предлагает пользователю ряд вопросов, тут же выводя при этом варианты ответов, которые можно выбрать в один клик. Подобный тип представления упрощает процесс, разбивая его на микроинтеракции, и делает его более неформальным.

                    Gotcha

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

                    Pepper

                    Виджет для сайтов, который группирует все доступные каналы связи и выводит их списком по клику на приметную иконку в углу экрана. Оформить окошко и получить готовый код можно прямо на сайте разработчика. Доступны для включения страницы в популярных соцсетях (Facebook, Vkontakte, Twitter, Instagram), Skype, Whatsapp, электронная почта, вебсайты, номер телефона.

                    Canny

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

                    Контент

                    PingGo

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

                    Hemingway Editor 3.0

                    Хэмингуэй, возможно, автор не для всех, но его лаконичность и ёмкость —это то, чего в наши дни определенно не хватает многим сайтам и пресс-релизам. Инструмент с говорящим названием Hemingway Editor 3.0 использует алгоритмы, построенные на основании правил, которые сформулировал классик, чтобы анализировать тексты, указывая на проблемные места, предлагая альтернативы и давая общую оценку читабельности. Эти подсказки помогают сделать текст более сжатым, информативным и простым для восприятия. Для командной работы предусмотрена возможность выгружать текст с правками в Word и PDF-документы.

                    Everypixel

                    Сервис для подбора качественных и релевантных фотографий на ваш страницу или блог. Поиск производится по 50 с лишним ресурсов, которые включают как стоковые сайты бесплатных фотографий, так и платные коллекции, причем для последних подключена функция сравнения цен. Сузить круг можно, сортируя выдачу по различным параметрам (от ориентации до типа изображения) и производя поиск по схожему изображению. Разработчики описывают свое творение следующим образом: «как Google Images, только для лицензируемых изображений».

                    Брендинг


                    Emblem

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

                    Viable

                    Приложение Viable проверяет, не используется ли название, которое вы запланировали для своего проекта, другими продуктами или компаниями. В числе источников, по котором производится поиск, создатели называют такие ресурсы, как Domainr, Markify, App Store, Product Hunt, Angel List и Pearson.

                    Startup Pitch Decks

                    Подборка презентаций продукта от компаний, которые впоследствии стали крупными игроками в своём секторе — хороший источник идей, вдохновения и размышлений о рецепте успеха.

                    Комментарии (0)

                      Let's block ads! (Why?)