[Lenguaje R] En vista de la aceleración del cálculo del modelo de entrenamiento grabando dentro de mil millones de bucles

1. Introducción

La máquina principal del autor es MBA M1芯片(8+256). Una tarde, cuando consolidé el ciclo, de repente pensé en un problema. El ciclo pequeño se puede ejecutar rápidamente, y el ciclo mediano apenas está allí, y funciona muy lentamente con un poco de fortaleza. Aunque la CPU está ocupada al 100 %, los 8 núcleos parecen aflojarse, pero la 4核心8线程manzana negra que me arrojaron está llena, lo que indica que hay algo mal con ARM cuando es multiproceso.

La siguiente figura es cuando se calcula un modelo de entrenamiento dentro de 1 billón top:

2 varios bucles

2.1 Sumas hasta 100

### for
sum <- 0
for (i in 1:100) {
    
    
  sum <- sum + i
}
print(sum)

### while
sum <- 0
i <- 1
while (i <= 100) {
    
    
  sum <- sum + i
  i <- i + 1
}
print(sum)

2.2 Suma de números pares/impares hasta 100

### for
odd_sum <- 0
even_sum <- 0

for (i in 1:100) {
    
    
  if (i %% 2 == 0) {
    
    
    even_sum <- even_sum + i
  } else {
    
    
    odd_sum <- odd_sum + i
  }
}

print(paste("奇数和:", odd_sum))
print(paste("偶数和:", even_sum))

### while
odd_sum <- 0
even_sum <- 0
i <- 1

while (i <= 100) {
    
    
  if (i %% 2 == 0) {
    
    
    even_sum <- even_sum + i
  } else {
    
    
    odd_sum <- odd_sum + i
  }
  i <- i + 1
}

print(paste("奇数和:", odd_sum))
print(paste("偶数和:", even_sum))

3 bucles múltiples

Lo siguiente solo registra y proporciona ideas, análisis específicos de la situación específica, pero una cosa es 思维模式muy beneficiosa.

3.1 Vectorización

Suponga que calcula el producto punto de dos vectores x e y, use el ciclo for para viajar por separado, multiplique y agregue:

x <- c(1, 2, 3, 4, 5)
y <- c(5, 4, 3, 2, 1)
dot_product <- 0
for (i in 1:length(x)) {
    
    
  dot_product <- dot_product + x[i] * y[i]
}
print(dot_product)

La vectorización se puede entender como un check-in, lo más destacado es sum()la suma *:

x <- c(1, 2, 3, 4, 5)
y <- c(5, 4, 3, 2, 1)
dot_product <- sum(x * y)
print(dot_product)

3.2 Fusión de bucles

Suponga que cada elemento de dos matrices A y B se recorre, se suma y el resultado se almacena en la matriz C. Esto se puede lograr usando dos bucles for anidados:

A <- matrix(1:9, 3, 3)
B <- matrix(10:18, 3, 3)
C <- matrix(0, 3, 3)
for (i in 1:nrow(A)) {
    
    
  for (j in 1:ncol(A)) {
    
    
    C[i, j] <- A[i, j] + B[i, j]
  }
}
print(C)

#输出结果:
     [,1] [,2] [,3]
[1,]   11   13   15
[2,]   17   19   21
[3,]   23   25   27

Pero para comprender el propósito de este tipo, la idea de fusionar bucles aquí es solo la suma de números correspondientes uno a uno en matrices:

A <- matrix(1:9, 3, 3)
B <- matrix(10:18, 3, 3)
C <- A + B
print(C)

3.3 aplicar función

Supongamos que hay un tapete de matriz bidimensional de 3x3, y cada elemento de la matriz debe elevarse al cuadrado. Podemos hacer esto usando un bucle for:

mat <- matrix(1:9, 3, 3)
result <- matrix(0, 3, 3)
for (i in 1:nrow(mat)) {
    
    
  for (j in 1:ncol(mat)) {
    
    
    result[i, j] <- mat[i, j] ^ 2
  }
}
print(result)

Usar apply+ function:

mat <- matrix(1:9, 3, 3)
result <- apply(mat, c(1, 2), function(x) x^2)
print(result)

3.4 Operaciones matriciales

Suponga que necesita calcular la matriz inversa de una matriz A, use la operación de bucle y matriz para lograr:

A <- matrix(c(1, 2, 3, 4), 2, 2)
det_A <- A[1, 1] * A[2, 2] - A[1, 2] * A[2, 1]
adj_A <- matrix(c(A[2, 2], -A[1, 2], -A[2, 1], A[1, 1]), 2, 2)
A_inv <- adj_A / det_A
print(A_inv)

#输出结果:
     [,1] [,2]
[1,] -2.0  1.0
[2,]  1.5 -0.5

Para optimizar este paso, es muy simple, use directamente solve():

A <- matrix(c(1, 2, 3, 4), 2, 2)
A_inv <- solve(A)
print(A_inv)

3.5 tarea de descomposición foreach

foreachImplementar un bucle for de subprocesos múltiples con el paquete

library(foreach)
library(doParallel)

# 创建一个1000行,1000列的矩阵
m <- matrix(runif(1000000), nrow = 1000)

# 初始化并行计算环境
cl <- makeCluster(detectCores())
registerDoParallel(cl)

# 使用foreach包和%dopar%运算符进行并行计算
result <- foreach(i = 1:nrow(m), .combine = "+") %dopar% sum(m[i, ])

# 结束并行计算环境
stopCluster(cl)

# 输出结果
print(result)

Algunas personas dirán, ¿no es esto solo usar una función?

Sí, pero no del todo, de lo contrario, algunas personas saben cómo usar esta función, pero algunas personas necesitan calcular paso a paso (por no decir que el cálculo paso a paso no es bueno, solo si lo ha calculado usted mismo y lo ha entendido, ¿Puedes saber cómo profundizar y simplificarlo?)

4. Discusión

Si solo conoce una función, la conoce pero no sabe por qué, pero solo conoce el proceso de cálculo y puede calcularla paso a paso como antes de la optimización. Gracias al rápido desarrollo de Internet, casi todos tienen todo tipo de herramientas convenientes y métodos de código abierto, 调包侠pero cuando la asistencia preparada no es suficiente, aún es necesario volver a la capa inferior . Recientemente, me ha conmovido profundamente. Ya sea que se trate de minería de datos, aprendizaje automático, aprendizaje profundo, inteligencia artificial o pila completa, el final del análisis es el algoritmo .

Supongo que te gusta

Origin blog.csdn.net/weixin_48093827/article/details/130508856
Recomendado
Clasificación