| |
write
|
Функция уже компактна и эффективна, но есть несколько идей, как её можно ещё улучшить:
1. Улучшение читаемости и интерфейса
Добавить явное описание предназначения функции и улучшить её интерфейс:
Переименовать функцию в более осмысленное название, например, calculateLinearRegression.
Использовать структуру для возвращаемых значений, чтобы вместо std::tuple обеспечить понятность полей.
2. Избегание вычислений с малыми значениями
Добавить защиту от численных ошибок, если дисперсия ssX или ssY слишком мала.
3. Подготовка к многопоточности
Если векторы очень большие, можно использовать параллельный подход, например, с помощью std::reduce или std::transform_reduce.
#include <cmath>
#include <stdexcept>
#include <vector>
#include <numeric>
struct LinearRegressionResult {
float rSquared;
float yIntercept;
float slope;
};
LinearRegressionResult calculateLinearRegression(const std::vector<float>& xVals, const std::vector<float>& yVals, int start, int end) {
if (start >= end) {
throw std::invalid_argument("Invalid range: 'start' must be less than 'end'.");
}
if (start < 0 || end > static_cast<int>(xVals.size()) || end > static_cast<int>(yVals.size())) {
throw std::out_of_range("Invalid range: 'start' and 'end' must be within the bounds of the input vectors.");
}
float sumX = 0, sumY = 0, sumXSq = 0, sumYSq = 0, sumXY = 0;
float count = static_cast<float>(end - start);
for (int i = start; i < end; ++i) {
sumX += xVals[i];
sumY += yVals[i];
sumXSq += xVals[i] * xVals[i];
sumYSq += yVals[i] * yVals[i];
sumXY += xVals[i] * yVals[i];
}
float meanX = sumX / count;
float meanY = sumY / count;
float ssX = sumXSq - sumX * meanX;
float ssY = sumYSq - sumY * meanY;
if (std::abs(ssX) < 1e-6 || std::abs(ssY) < 1e-6) {
throw std::runtime_error("Insufficient variance in data.");
}
float covariance = sumXY - sumX * meanY;
float slope = covariance / ssX;
float yIntercept = meanY - slope * meanX;
float rNumerator = covariance;
float rDenominator = std::sqrt(ssX * ssY);
float rSquared = (rDenominator > 0) ? (rNumerator / rDenominator) * (rNumerator / rDenominator) : 0;
return {rSquared, yIntercept, slope};
}
|
| |
create
|
11:37 10.12.2024 |
|
11:38 10.12.2024 |
|
№11191 |
/*
В целом, я не удивлен, почему рынок джуниор-программистов за последние несколько месяцев стал сильно проседать в Штатах. )))
*/
|
| |
create
|
|
| |
create
|
11:09 12.12.2024 |
|
11:20 12.12.2024 |
|
№11194 |
//===========================================================
//
// ТРЕТИЙ ПРИМЕР
// РЕШЕНИЕ ARC-ЗАДАЧ ФРАНСУА ШОЛЛЕ
//
//===========================================================
Предлагаю порешать ARC-задачи Франсуа Шолле.
Я дам две картинки, нужно будет найти преобразование, которое из первой делает вторую. Сначал нам нужно упростить исходные данные.
/* выкладываю в чат первые две картинки из это примера */
|
| |
write
|
Подумал об упрощении задачи for 54 seconds
Analysis of potential errors in the solution:
1. Initially, I tried various rotations and flips.
2. On careful checking, the 180-degree rotation matches almost perfectly the final arrangement of squares, considering the positions of unique colors like orange, gray, and light-blue.
3. Counting the colors before and after ensures the same number of each color. After rotating 180 degrees, each unique color from the original appears in the correct place corresponding to the final image.
4. A direct 180-degree rotation of the given 3x3 grid transforms the first image into the second image correctly.
Final Answer: Применив к исходному изображению поворот на 180 градусов (разворот на 2 раза по 90 градусов), мы получим второе изображение.
|
| |
create
|
Давай проверим твою гипотезу, даю на вход тестовую картинку, сгенерируй мне выход (новую картинку), основанный на правиле, которое ты реконструировал
/* выкладываю третью картинку, которая соответствует тесту */
|
| |
write
|
11:11 12.12.2024 |
|
11:12 12.12.2024 |
|
№11197 |
Thought about transformation hypothesis for 6 seconds
Анализ и проверка результата:
Предполагаемое правило – поворот исходного изображения на 180 градусов.
Дана новая тестовая картинка (3x3). Исходная матрица цветов по строкам (сверху вниз, слева направо):
Строка 1: серый (Gray), серый (Gray), красный (Red)
Строка 2: синий (Blue), чёрный (Black), чёрный (Black)
Строка 3: чёрный (Black), чёрный (Black), чёрный (Black)
Применяем поворот на 180 градусов. При таком повороте верхняя левая ячейка переходит в нижнюю правую и так далее. Результирующая матрица по строкам будет:
Новая строка 1 (бывшая строка 3, задом наперёд): чёрный (Black), чёрный (Black), чёрный (Black)
Новая строка 2 (бывшая строка 2, задом наперёд): чёрный (Black), чёрный (Black), синий (Blue)
Новая строка 3 (бывшая строка 1, задом наперёд): красный (Red), серый (Gray), серый (Gray)
Итоговый результат (выходная картинка после преобразования):
Black Black Black
Black Black Blue
Red Gray Gray
|
| |
create
|
Хорошо, но я хочу получить картинку, дай программу генерации на С++ с использованием OpenCV
|
| |
write
|
Thought about C++ OpenCV image generation for a few seconds
Анализ и исправление:
Программа на C++ с использованием OpenCV для создания изображения 3x3 клеток по 66x66 пикселей каждая, без using namespace, с чёткими комментариями.
Цвета и итоговый результат соответствуют ранее описанному преобразованию (поворот на 180 градусов):
Строка 1: Black, Black, Black
Строка 2: Black, Black, Blue
Строка 3: Red, Gray, Gray
Проверить код на соответствие условию: код с OpenCV, без using namespace, комментарии на английском.
Итоговый код корректен, компилируем и генерируем rotated_result.png.
#include <opencv2/opencv.hpp> // Include OpenCV header
#include <vector>
int main() {
// Each cell is 66x66 pixels
const int cell_size = 66;
const int rows = 3;
const int cols = 3;
const int img_width = cols * cell_size;
const int img_height = rows * cell_size;
// Define BGR colors (OpenCV uses BGR format)
cv::Vec3b black(0, 0, 0);
cv::Vec3b blue(255, 0, 0); // Blue in BGR: (255, 0, 0)
cv::Vec3b red(0, 0, 255); // Red in BGR: (0, 0, 255)
cv::Vec3b gray(128, 128, 128);
// Define the resulting 3x3 color grid after rotation
// top row = row 0; each element is a cv::Vec3b color
std::vector<std::vector<cv::Vec3b>> color_grid = {
{black, black, black},
{black, black, blue},
{red, gray, gray}
};
// Create a blank image
cv::Mat img = cv::Mat::zeros(img_height, img_width, CV_8UC3);
// Fill the image with the colors from the grid
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
cv::Vec3b color = color_grid[r][c];
// Fill the cell (r,c) with the specified color
for (int y = r * cell_size; y < (r + 1) * cell_size; y++) {
for (int x = c * cell_size; x < (c + 1) * cell_size; x++) {
img.at<cv::Vec3b>(y, x) = color;
}
}
}
}
// Save the result as PNG
cv::imwrite("rotated_result.png", img);
return 0;
}
|
| |
create
|
/*
Я запускаю написанную функцию и получаю такое изображение,
сравните его с выходным тестовым)))
*/
|
| |
write
|
Это конечно капец, даже не знаю, просто капец. Вот так с первой попытки выплюнул целый MLP на сишке, который зафурычил сразу БЕЗ ОШИБОК!!!
Ну не знаю… те кто кодит наверно поймут насколько это может ускорить процессы разработки.
Понятное дело что так наверно только с вдоль и поперек выпелеными, точнее ззапиленными в опилки алгоритмами возможно, но капец, просто капец.
Хотя, также наверно, как с калькуляторами в своё время, даже нонешние технические спецы, забыли как считать в столбик и даже таблицу умножения, ещё перестоит узнать что забудут или знать не будут за ненадоностью, кодеры нового поколения.
Чую менеджмент будет с новым рвением опять пытаться конвеерезировать труд кодеров, до полного примитива, чтобы можно было брать с улицы как в макдоналдс и за пару месяцев пускать в бой. В идеале чтобы "разрабатывали" исполнительные менеджеры гуманитарии, вот так вот промтами.
напиши мне на C MLP с бэкпропом:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
typedef struct {
int* layers;
int num_layers;
float** neurons;
float*** weights;
float** biases;
float learning_rate;
} MLP;
float random_float() {
return ((float)rand() / RAND_MAX) * 2 - 1;
}
float activate(float value) {
return 1.0f / (1.0f + expf(-value));
}
float derivative(float value) {
return value * (1.0f - value);
}
MLP* create_mlp(int* layers, int num_layers, float learning_rate) {
MLP* mlp = (MLP*)malloc(sizeof(MLP));
mlp->layers = layers;
mlp->num_layers = num_layers;
mlp->learning_rate = learning_rate;
mlp->neurons = (float**)malloc(num_layers * sizeof(float*));
mlp->biases = (float**)malloc(num_layers * sizeof(float*));
mlp->weights = (float***)malloc(num_layers * sizeof(float**));
for (int i = 0; i < num_layers; i++) {
mlp->neurons[i] = (float*)calloc(layers[i], sizeof(float));
mlp->biases[i] = (float*)malloc(layers[i] * sizeof(float));
if (i > 0) {
mlp->weights[i] = (float**)malloc(layers[i] * sizeof(float*));
for (int j = 0; j < layers[i]; j++) {
mlp->weights[i][j] = (float*)malloc(layers[i - 1] * sizeof(float));
for (int k = 0; k < layers[i - 1]; k++) {
mlp->weights[i][j][k] = random_float();
}
mlp->biases[i][j] = random_float();
}
}
}
return mlp;
}
void forward(MLP* mlp, float* inputs) {
for (int i = 0; i < mlp->layers[0]; i++) {
mlp->neurons[0][i] = inputs[i];
}
for (int i = 1; i < mlp->num_layers; i++) {
for (int j = 0; j < mlp->layers[i]; j++) {
float sum = 0.0f;
for (int k = 0; k < mlp->layers[i - 1]; k++) {
sum += mlp->neurons[i - 1][k] * mlp->weights[i][j][k];
}
mlp->neurons[i][j] = activate(sum + mlp->biases[i][j]);
}
}
}
void backward(MLP* mlp, float* expected) {
float** errors = (float**)malloc(mlp->num_layers * sizeof(float*));
for (int i = 0; i < mlp->num_layers; i++) {
errors[i] = (float*)calloc(mlp->layers[i], sizeof(float));
}
for (int i = mlp->num_layers - 1; i >= 0; i--) {
if (i == mlp->num_layers - 1) {
for (int j = 0; j < mlp->layers[i]; j++) {
errors[i][j] = mlp->neurons[i][j] - expected[j];
}
}
else {
for (int j = 0; j < mlp->layers[i]; j++) {
float error = 0.0f;
for (int k = 0; k < mlp->layers[i + 1]; k++) {
error += errors[i + 1][k] * mlp->weights[i + 1][k][j];
}
errors[i][j] = error;
}
}
for (int j = 0; j < mlp->layers[i]; j++) {
mlp->biases[i][j] -= mlp->learning_rate * errors[i][j] * derivative(mlp->neurons[i][j]);
if (i > 0) {
for (int k = 0; k < mlp->layers[i - 1]; k++) {
mlp->weights[i][j][k] -= mlp->learning_rate * errors[i][j] * derivative(mlp->neurons[i][j]) * mlp->neurons[i - 1][k];
}
}
}
}
for (int i = 0; i < mlp->num_layers; i++) {
free(errors[i]);
}
free(errors);
}
void train(MLP* mlp, float** inputs, float** outputs, int num_samples, int epochs) {
for (int epoch = 0; epoch < epochs; epoch++) {
for (int i = 0; i < num_samples; i++) {
forward(mlp, inputs[i]);
backward(mlp, outputs[i]);
}
}
}
void print_output(MLP* mlp, float** inputs, int num_samples) {
for (int i = 0; i < num_samples; i++) {
forward(mlp, inputs[i]);
printf("Input: ");
for (int j = 0; j < mlp->layers[0]; j++) {
printf("%.2f ", inputs[i][j]);
}
printf("-> Output: ");
for (int j = 0; j < mlp->layers[mlp->num_layers - 1]; j++) {
printf("%.2f ", mlp->neurons[mlp->num_layers - 1][j]);
}
printf("\n");
}
}
int main() {
srand(time(NULL));
int layers[] = { 2, 4, 1 };
MLP* mlp = create_mlp(layers, 3, 0.01f);
float inputs[4][2] = {
{0.0f, 0.0f},
{0.0f, 1.0f},
{1.0f, 0.0f},
{1.0f, 1.0f}
};
float outputs[4][1] = {
{0.0f},
{1.0f},
{1.0f},
{0.0f}
};
float* input_ptrs[4] = { inputs[0], inputs[1], inputs[2], inputs[3] };
float* output_ptrs[4] = { outputs[0], outputs[1], outputs[2], outputs[3] };
train(mlp, input_ptrs, output_ptrs, 4, 100000);
print_output(mlp, input_ptrs, 4);
return 0;
}
|
| |
create
|
13:54 12.12.2024 |
|
13:57 12.12.2024 |
|
№11203 |
qwerty: Вот так с первой попытки выплюнул целый MLP на сишке, который зафурычил сразу БЕЗ ОШИБОК!!!
Да, похоже современно программирование будет начинаться не с "Hello World!" как в олдскульные ламповые времена, а с MLP или CNN))) В этой задачке очень много зависит от предобработки, выбора активационной функции и всяческих нормировок областей определений, так вот LLM в состоянии давать осмысленные рекомендации в этой части, то есть с ней можно работать даже на уровне постановки.
В такие минуты я особенно остро благодарю судьбу, что я - архитектор, а не кодер, профессия кодера, похоже, в самом деле будет полностью закрыта решениями трансформеров, но зато именно умение в архитектуру, стратегию и проектное вИдение выходит на первый план и становится важнейшим навыком))
Что касается людей с гуманитарным и философским складом ума, то они вообще стопроцентно перебираются в область пособий, безусловных доходов и прочих социальных акций подножного корма)))
|
| |
create
|
11:45 13.12.2024 |
|
11:45 13.12.2024 |
|
№11204 |
Мир чистогана как он есть: сейчас в своей работе почти всегда параллельно использую o1 для систематизации, обсуждения, дописывания мелких функций, оптимизации, итд. И уже выбрал месячный лимит на запросы))), который некоторое время назад казался мне большим) Быстро, конечно, привыкаешь к новым инструментам, впрочем 4о тоже весьма хорош, особенно, если не уходить в сложные рассуждения))
|
| |
create
|
14:58 13.12.2024 |
|
14:58 13.12.2024 |
|
№11205 |
|
| |
write
|
Да, толковая статейка, благодарю, и коменты весьма разумны.
Было бы интересно посмотреть различные варианты промтовой разработки боле комплексных проектов, до продуктового уровня, хотя бы mvp-шного. Чтобы по максимуму была попытка "не влезать ручками" и выяснить где и как ии-шка начинает плавать и больше вредить чем помогать.
Понятно что отдельные алгоритмы вдоль и поперёк запиленные в опилки, иишка будет выдавать в шедевральном виде. Но как на счет реальной кодерской боли, интеграции множества витиеватых подсистем с часто хреновой структурой и плохо совместимыми интерфейсами, внесение мало вразумительных изменений ломающих архитетуру и тд. Как вообще с работой с огромными проектами из разнородных компонентов в сотни тысяч и миллионы строк кода, на разных ЯП и фреймворках, как ИИ будет искать оптимальные пути что то в этом поменять, по указке эффективного менеджера с садистскими наклонностями?
|
| |
create
|
14:14 14.12.2024 |
|
14:15 14.12.2024 |
|
№11207 |
qwerty: Было бы интересно посмотреть различные варианты промтовой разработки боле комплексных проектов, до продуктового уровня, хотя бы mvp-шного. Чтобы по максимуму была попытка "не влезать ручками" и выяснить где и как ии-шка начинает плавать и больше вредить чем помогать.
Про это никто не покажет из-за полиси, может только русские какие. Я доходил до границ canvas, когда она писала, что ваш буффер полностью заполнен и останавливала постить код))) Сложные проекты получаются пока не очень, в какой-тро момент происходит сбой и приходится восстанавливать контекст с самого начала. Также сложные классы и наследования у меня вызвали вопросы, хотя начальное проектирование было офигенным. То есть текущее использование - небольшие функции с детально проработанным промтом. Вообще, промт очень важен.
OpenAI вчера выкатили "проекты", где вроде как можно собирать общий контекст. Очень интересно попробовать, но у меня пока не обновилось, может они выложат позже. Идея контекстного проекта с несколькими чатами - это реальное подспорье в разработке, особенно, если эти чаты можно будет как-то слойно делить на низкий и высокий уровень решений.
|
| |
write
|
Egg:
Про это никто не покажет из-за полиси, может только русские какие. Так речь не о конторских гребцах и их рабочие проекты за зп., много же студентов, опенсорса, петроектов и тд. причем побольше конторского кода. Линукс как то умудрились написать без всех этих юридических страшилок и работает быстрее винды. Думаю будет скоро полно такого контента, платно и бесплатно. Появится на гитхабе раздел с промт-разработкой.
Egg: Я доходил до границ canvas, когда она писала, что ваш буффер полностью заполнен и останавливала постить код))) Сложные проекты получаются пока не очень, в какой-тро момент происходит сбой и приходится восстанавливать контекст с самого начала. Также сложные классы и наследования у меня вызвали вопросы, хотя начальное проектирование было офигенным. То есть текущее использование - небольшие функции с детально проработанным промтом. Вообще, промт очень важен.
В трансформерах многое рандомно, да ещё с "эффектом бабочки", слово за слово, траектории броуновские, сильно удивительно как на чистом принципе прогнозирования следующего токена по контексту, выходит получать работающий код. Думаю они уже наворотили не одну эвристику поверх или даже вообще иной способ обучения в дополнение, чтобы так получалось с кодом. С ЕЯ текстом как бы понятно, там всё "в общем", а код...
|
| |
create
|
o1/4o-canvas: Подумал об упрощении задачи for 54 seconds
Analysis of potential errors in the solution:
1. Initially, I tried various rotations and flips.
2. On careful checking, the 180-degree rotation matches almost perfectly the final arrangement of squares, considering the positions of unique colors like orange, gray, and light-blue.
3. Counting the colors before and after ensures the same number of each color. After rotating 180 degrees, each unique color from the original appears in the correct place corresponding to the final image.
4. A direct 180-degree rotation of the given 3x3 grid transforms the first image into the second image correctly.
Final Answer: Применив к исходному изображению поворот на 180 градусов (разворот на 2 раза по 90 градусов), мы получим второе изображение.
А если принципом преобразования будет поворот на 180 градусов,
с заменой цвета Black на Blue второго элемента третьей строки
исходной матрицы, то сможет ли он определить э тот принцип без
подсказки?
|
| |
create
|
18:20 15.12.2024 |
|
22:48 15.12.2024 |
|
№11213 |
Влад: А если?
По сослагательным наклонениям, розовым мечтам о несбывшемся и прочим дебильностям (не имеющих никакого отношения к реальности) у нас есть отдельный (пусть и немножко съехавший с катушек) "специалист" - Лаврушка.
Я же просто показал решение заявленной Андреем задачки. Хотите поэспериментировать с сетями - флаг Вам в руки и барабан на шею, подписывайтесь, экспериментируйте. Факты показывают, что о1/4о уже умнее любого гуманитария))
|
| |
create
|
Egg:Влад: А если?
По сослагательным наклонениям, розовым мечтам о несбывшемся и прочим дебильностям (не имеющих никакого отношения к реальности) у нас есть отдельный (пусть и немножко съехавший с катушек) "специалист" - Лаврушка.
Я же просто показал решение заявленной Андреем задачки. Хотите поэспериментировать с сетями - флаг Вам в руки и барабан на шею, подписывайтесь, экспериментируйте. Факты показывают, что о1/4о уже умнее любого гуманитария))
Я верю Вам.
Начал то он (о1/4о) геометром (вращение на 180 градусов), а закончил
комбинаториком (задом наперёд ). Т.е. геометрия и комбинаторика – это
аспекты (стороны) единого целого. Т.е. он (люди его создавшие) видит
мир через некую многомерную шкалу (метрику) измерений. Поэтому
ему не составит труда подметить особенность (правило), предложенного
мной перехода из исходного состояния в требуемое состояние.
Или составит?
|
|
|